Skip to main content
Glama

Server Details

SEO and AI-visibility operator tools: site health, ranked actions, ranks, visitor behavior.

If you are the author of this connector, you can claim ownership by verifying the domain or GitHub account it belongs to. Claimed connector authors can inspect health checks, view analytics, and manage their listing.
Status
Healthy
Uptime
99.9% over 21 days
Last Tested
Transport
Streamable HTTP ยท MCP 2025-11-25
URL
Repository
bapierre/getcited-mcp
GitHub Stars
0
Server Listing
getcited

TDQS

A3.9/5.0

Scored across 29 tools

Disambiguation4/5

Most tools have clearly distinct workflow roles, and the descriptions explicitly differentiate queuing tools from read tools and action-choosing tools from action-detail tools. However, the large number of related read/action/list variants creates some surface overlap that an agent must carefully parse.

Naming Consistency4/5

The set is overwhelmingly snake_case, mostly following a verb_noun pattern such as add_project, list_actions, check_rankings, and complete_action. A few names like geo_summary and rank_history are noun-only, which is a minor deviation but still readable and consistent.

Tool Count2/5

At 29 tools, the surface is heavy for the domain and exceeds the typical well-scoped range. While many tools serve real workflow steps, several read/diagnostic tools could likely be consolidated without losing capability.

Completeness4/5

The server covers the full SEO/GEO growth loop: project setup, auditing, action management, keyword and rank tracking, AI citation checks, analytics, opportunities, and content briefs. Minor gaps exist, such as updating or removing individual tracked keywords or GEO prompts, but agents can work around them.

Available Tools

29 tools
add_geo_promptsAdd GEO promptsA
Idempotent
Inspect

Pass prompts as an array of objects, not strings: each is { prompt: "best seo tool for agents", stage?: "tofu" | "mofu" | "bofu", format?: "keyword" | "conversational" | "list" }, with the projectId from add_project or list_projects. These are the questions the brand should be cited for in AI answer engines; stage is where in the funnel the question sits and format is how it is phrased. Returns added; a prompt already tracked is skipped, so calling again is safe, and adding costs no quota. Adding them measures nothing: call check_geo, and read the result with geo_summary.

ParametersJSON Schema
NameRequiredDescriptionDefault
promptsYesArray of objects, one per prompt: [{ prompt: "best seo tool for agents", stage: "bofu" }]
projectIdYesProject id (a UUID) from add_project or list_projects, e.g. "0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30"

Output Schema

ParametersJSON Schema
NameRequiredDescription
addedYesRows inserted; duplicates are skipped

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already declare idempotentHint=true, destructiveHint=false and readOnlyHint=false, so the safety profile is partly covered. The description still adds real behavior: duplicates are skipped ('a prompt already tracked is skipped, so calling again is safe'), adding consumes no quota, and the return key is `added`. That is concrete disclosure beyond the annotation booleans.

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

Conciseness4/5

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

Dense but every clause carries weight: shape, source of projectId, meaning of the fields, dedupe/quota behavior, and the next-step chain. It is slightly long for one paragraph but front-loads the highest-risk detail (array of objects, not strings) first.

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

Completeness5/5

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

An output schema exists, so return details need not be expanded, and the description still names the `added` key plus the dedupe and quota semantics. Combined with the named follow-up tools, an agent has everything needed to call this correctly and know what to do next.

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

Parameters3/5

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

Schema description coverage is 100%, and the description's parameter guidance largely mirrors it: the nested object shape, the enum values, and the example prompt all appear in the schema. It reinforces rather than extends, adding only a domain gloss on what stage and format signify ('where in the funnel the question sits', 'how it is phrased') which the schema also states.

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

Purpose4/5

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

The description defines the resource concretely ('the questions the brand should be cited for in AI answer engines') and the action, and it distinguishes itself from siblings by naming check_geo and geo_summary as follow-ups. However, the purpose is embedded in the middle of a param-syntax-first paragraph rather than stated as a lead verb+resource, so an agent has to read past the mechanics to learn what the tool does.

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

Usage Guidelines5/5

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

Explicit routing is provided in both directions: projectId comes 'from add_project or list_projects', and after adding, the agent is told to 'call check_geo, and read the result with geo_summary'. It also warns that 'Adding them measures nothing', which preempts a misuse an agent would otherwise make.

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

add_keywordsAdd keywordsA
Idempotent
Inspect

Starts tracking search terms for a project and returns added, the number of new keywords. Pass terms as an array of plain search phrases (terms: ["seo tool", "rank tracker"]) with the projectId from add_project or list_projects. Terms are lowercased, and one already tracked is skipped, so calling again is safe. Adding measures no rank: call check_rankings for positions. Search volume and difficulty arrive within about ten minutes, looked up in one request pooled with other keywords, costing one keyword_lookups unit per keyword; read them with list_keywords.

ParametersJSON Schema
NameRequiredDescriptionDefault
termsYesThe search phrases to track, as plain strings, 1-200 per call: ["seo tool", "rank tracker"]
projectIdYesProject id (a UUID) from add_project or list_projects, e.g. "0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30"

Output Schema

ParametersJSON Schema
NameRequiredDescription
addedYesRows inserted; duplicates are skipped

TDQS

A4.9/5.0
Behavior5/5

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

The annotations already declare a non-destructive, idempotent write, and the description reinforces idempotency by explaining that already-tracked terms are skipped and repeated calls are safe. It adds behavioral context beyond annotations: lowercasing, ten-minute lookup timing, one pooled request, and a keyword_lookups cost per keyword.

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

Conciseness5/5

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

The description is front-loaded with the core action and return value, then efficiently covers parameter usage, idempotency, alternatives, and cost. Every sentence contributes useful information without repetition.

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

Completeness5/5

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

Given an output schema already exists, the description need not fully document return values, but it still names the returned field and explains how derived data later becomes available. With rich annotations and full schema coverage, an agent has everything needed to call the tool correctly.

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

Parameters4/5

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

Schema coverage is 100%, so the schema already documents both parameters fully. The description still adds semantic value by specifying plain-string phrases, lowercasing behavior, skip-existing behavior per term, and the source of projectId, though it does not add format detail beyond the schema.

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

Purpose5/5

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

The description states a specific verb and resource: starts tracking search terms for a project. It distinguishes the tool from siblings by naming check_rankings for positions and list_keywords for reading volume/difficulty.

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

Usage Guidelines5/5

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

It explicitly says to pass terms with a projectId from add_project or list_projects, notes that adding does not measure rank, and directs the agent to check_rankings and list_keywords for those alternatives. The when-to-use and when-not-to-use guidance is complete.

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

add_projectTrack a siteA
Idempotent
Inspect

Register the site you are working in, and get its project id back. Pass the domain you derived from this codebase (git remote, deployed URL, site config). Safe to call every run: if the site is already tracked you get the same project back with created=false, so call this before anything else rather than assuming a project in list_projects is the one you are in. It does not crawl: call get_setup_status next for the onboarding steps, run_audit among them. Returns projectId, the normalized domain, brandName and created. Private, loopback and internal hosts are refused as invalid_request; a plan's site limit answers quota_exceeded with metric sites. Without a plan the first site gets the one free audit, and the answer says what that includes.

ParametersJSON Schema
NameRequiredDescriptionDefault
domainYesDomain of the site you are working in, e.g. example.com
brandNameNoHow the brand is written, when it differs from the domain

Output Schema

ParametersJSON Schema
NameRequiredDescription
noteNoPresent only on the free preview: what it includes and what it does not
planNoPresent only when there is no subscription: this account is on the free preview
domainYesThe normalized domain that is tracked
createdYestrue if this call registered the site, false if it was already tracked
brandNameYes
projectIdYesPass this to every other tool

TDQS

A4.8/5.0
Behavior5/5

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

Annotations cover the safety profile (readOnlyHint=false, idempotentHint=true, destructiveHint=false), and the description adds substantial context beyond them: idempotent re-calls return created=false, it does not crawl, private/loopback/internal hosts are refused as invalid_request, and quota failures surface as quota_exceeded with metric sites. This is rich behavioral disclosure that does not contradict the annotations.

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

Conciseness4/5

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

Front-loaded with the core action and idempotency contract, then edge cases. It is dense but nearly every clause carries operative information; only the trailing free-audit clause is somewhat incidental.

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

Completeness5/5

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

Although an output schema exists (so return values need not be spelled out), the description still names projectId, normalized domain, brandName and created, and covers error paths and prerequisites. Nothing an agent needs to call this correctly is missing.

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

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3, but the description adds derivation guidance for the required domain param ('the domain you derived from this codebase (git remote, deployed URL, site config)') and notes the returned normalized domain, which goes beyond the schema's generic example.

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

Purpose5/5

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

States a specific verb+resource: 'Register the site you are working in, and get its project id back.' It clearly distinguishes itself from siblings like list_projects, remove_project, and get_setup_status by naming the exact action and the artifact returned.

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

Usage Guidelines5/5

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

Explicitly says to 'call this before anything else rather than assuming a project in list_projects is the one you are in,' naming the alternative tool and the condition that selects this one. It also routes the next step ('call get_setup_status next').

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

check_geoCheck AI answer engines nowAInspect

Queues a run of every tracked GEO prompt against each configured AI answer engine and returns status, jobId and the prompt count. The work runs asynchronously in the worker and takes minutes; this returns as soon as it is queued. Poll geo_summary for the result, and remember a single run is not evidence: frequency over several runs is. Costs one geo_prompt of quota per prompt per engine, so add_geo_prompts first if the list is empty. Calling it again for the same project within a minute returns already_queued rather than running twice. If the last run is under 20 hours old it returns fresh and bills nothing: runs on different days are the independent samples geo_summary needs, so read it instead, or pass force: true.

ParametersJSON Schema
NameRequiredDescriptionDefault
forceNoRe-check even though the last check is under 20 hours old. Bills again; leave unset unless a same-day re-check is genuinely needed
projectIdYesProject id (a UUID) from add_project or list_projects, e.g. "0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30"

Output Schema

ParametersJSON Schema
NameRequiredDescription
hintNoPresent only with nothing_to_check: the tool to call before checking again
jobIdYesJob id, null when this call was deduplicated into an already-queued run
statusYesqueued when this call created the job. already_queued when the same job for this project was enqueued moments ago and this call was deduplicated: the work is coming and nothing extra was billed. nothing_to_check when the project tracks nothing for this run: no job was enqueued, nothing was billed, and hint names the tool to call first. fresh when the last check is under 20 hours old: nothing was enqueued or billed, read the existing result now, and pass force: true only if a re-check today is genuinely needed.
promptsYesActive GEO prompts the run will ask, once on every configured engine; 0 queues nothing
pollWithYesCall geo_summary once the worker has finished the run
lastCheckedAtNoISO time of the project's newest check of this kind, null when never checked
nextCheckAfterNoPresent only with fresh: when an unforced check will run again

TDQS

A4.8/5.0
Behavior5/5

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

Goes well beyond the annotations: asynchronous worker execution that returns as soon as queued, a 60-second dedup that yields already_queued, a 20-hour freshness window that returns fresh and bills nothing, and quota cost of one geo_prompt per prompt per engine. These are the operational facts an agent needs and none are captured by readOnlyHint/openWorldHint.

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

Conciseness4/5

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

Dense but front-loaded: the primary action and async contract come first, followed by result-routing, sampling caveat, and billing/quota rules. Every sentence carries distinct information, though the paragraph is long enough that an agent must read carefully.

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

Completeness5/5

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

With an output schema present, return-value detail is unnecessary, and the description still covers the async lifecycle, deduplication, freshness, quota, and the correct follow-up call. Nothing needed to invoke it correctly is missing.

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

Parameters4/5

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

Schema coverage is 100% and every parameter is documented, so baseline is 3. The description adds consequential semantics the schema states only thinly: quota billing on force and the 20-hour freshness gate that makes force meaningful.

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

Purpose5/5

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

States a specific verb and resource ('queues a run of every tracked GEO prompt against each configured AI answer engine') and names what it returns (status, jobId, prompt count). It is clearly distinguishable from the adjacent geo_summary, which it explicitly directs the agent to poll.

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

Usage Guidelines5/5

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

Gives explicit when-to-use/when-not rules: add_geo_prompts first if the list is empty, read geo_summary instead when the last run is under 20 hours old, and pass force only for a genuine same-day re-check. It also states the sampling rationale ('frequency over several runs is').

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

check_rankingsCheck keyword rankings nowAInspect

Queues a search-position check (top 30 results) for every keyword tracked on this project and returns status, jobId and the keyword count. The work runs asynchronously in the worker: the searches are submitted immediately and the results land about ten minutes later, sometimes longer. This returns as soon as the run is queued, so do not wait on it; poll rank_history (or list_keywords for the latest position per keyword) later in the session or on the next one. Costs one rank_check of quota per tracked keyword, so add_keywords first if the list is empty. Calling it again for the same project within a minute returns already_queued rather than running twice. If the last check is under 20 hours old it returns fresh and bills nothing: positions do not move within a day, so read list_keywords instead, or pass force: true.

ParametersJSON Schema
NameRequiredDescriptionDefault
forceNoRe-check even though the last check is under 20 hours old. Bills again; leave unset unless a same-day re-check is genuinely needed
projectIdYesProject id (a UUID) from add_project or list_projects, e.g. "0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30"

Output Schema

ParametersJSON Schema
NameRequiredDescription
hintNoPresent only with nothing_to_check: the tool to call before checking again
jobIdYesJob id, null when this call was deduplicated into an already-queued run
statusYesqueued when this call created the job. already_queued when the same job for this project was enqueued moments ago and this call was deduplicated: the work is coming and nothing extra was billed. nothing_to_check when the project tracks nothing for this run: no job was enqueued, nothing was billed, and hint names the tool to call first. fresh when the last check is under 20 hours old: nothing was enqueued or billed, read the existing result now, and pass force: true only if a re-check today is genuinely needed.
keywordsYesTracked keywords the run will check, one rank_check of quota each; 0 queues nothing
pollWithYesCall rank_history once the worker has finished the run
lastCheckedAtNoISO time of the project's newest check of this kind, null when never checked
nextCheckAfterNoPresent only with fresh: when an unforced check will run again

TDQS

A4.8/5.0
Behavior5/5

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

Annotations only declare flags (not read-only, not idempotent, not destructive, open-world); the description adds the substantive behavior they cannot: asynchronous worker execution, ~10 minute latency, immediate return with status/jobId/count, polling guidance, quota cost of one rank_check per keyword, the already_queued dedupe within a minute, and the 20-hour fresh/no-bill rule.

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

Conciseness4/5

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

Front-loaded with what the tool does, then cost, dedupe, and billing caveats in dense but non-redundant sentences. Every sentence carries operational information, though the async/polling/billing cluster is long enough that it could be tightened slightly.

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

Completeness5/5

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

For an async, quota-costing mutation with an output schema already present, the description covers timing, polling, cost, dedupe, and fallback behavior โ€” everything an agent needs before calling it. Nothing material is missing.

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

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3 and the schema already documents both params. The description nonetheless explains the rationale behind force (overriding the 20-hour window at the cost of another bill) and the empty-list precondition for projectId usage, adding meaning beyond the field descriptions.

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

Purpose5/5

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

States a specific verb and resource with scope: 'Queues a search-position check (top 30 results) for every keyword tracked on this project'. It also names the sibling tools (rank_history, list_keywords) an agent might confuse it with, so the operation is distinguishable 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.

Usage Guidelines5/5

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

Explicit when-to-use and when-not: read list_keywords/rank_history later rather than waiting, read list_keywords instead if the last check is under 20 hours old, add_keywords first if the list is empty, and pass force only for a genuine same-day re-check. Alternatives and prerequisites are all named.

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

claim_actionClaim an actionA
Idempotent
Inspect

Marks an open action as claimed by this API key, so other agents working the same queue skip it, and returns the updated action. Only an open action can be claimed: one already claimed (by any agent, this one included), done or dismissed answers not_found, so a repeat call changes nothing. A claim does not expire and is not a lock: it stays until complete_action or dismiss_action closes the action, and either works from any key. Claiming is optional; complete_action also accepts an open action. Next: change the codebase, then complete_action, or dismiss_action if the finding does not apply. Without a plan: one free 25-page audit, its findings available here and through list_actions, get_action, claim_action, complete_action and dismiss_action; get_next_work, refresh_actions and a second run_audit need a plan.

ParametersJSON Schema
NameRequiredDescriptionDefault
actionIdYesAction id (a UUID) from the id field of a list_actions row, an exampleActionIds entry of a group, or get_next_work
projectIdYesProject id (a UUID) from add_project or list_projects, e.g. "0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30"

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
noteYesWhy the agent closed this: required on dismissal, optional on completion
typeYesCategory of problem
titleYes
doneAtYes
statusYes
payloadYesEvidence; shape varies by type
notFoundNoactionIds that named no open finding of this project: already closed, or not ours
priorityYes1 is most urgent, 5 least
claimedAtYes
commitShaYesThe commit the agent reported when completing this, if it reported one
createdAtYesWhen the action was filed as an ISO 8601 timestamp
projectIdYes
rationaleYesWhat was measured and why it matters
refreshIdYesThe action-list refresh that filed this action, if any
targetUrlYesThe affected URL, if the problem is page-level
updatedAtYesWhen the action last changed as an ISO 8601 timestamp
alsoClosedNoFurther findings closed by this call's actionIds, beyond the one reported here
claimedByApiKeyIdYes

TDQS

A4.6/5.0
Behavior5/5

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

Goes well beyond the annotations by disclosing the state machine and concurrency semantics: claims do not expire, are not locks, persist until complete_action or dismiss_action, work from any key, and a repeat claim on a non-open action answers not_found so nothing changes. It also flags plan-gated capabilities, which 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.

Conciseness4/5

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

Front-loads the core action and semantics in the first two sentences, and the discussion of non-expiring claims versus locks earns its place. The closing pricing/plan sentence is only loosely tied to invoking this tool and slightly dilutes focus.

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

Completeness5/5

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

An output schema exists, so return-value detail is unnecessary, yet the description still notes it returns the updated action. Combined with the claim lifecycle, repeat-call behavior, and next-step routing, an agent has everything needed to call this correctly.

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

Parameters3/5

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

Schema description coverage is 100% and both parameters are documented in-schema (including UUID format and where each id comes from). The description adds no additional argument-level meaning, so the baseline 3 applies.

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

Purpose5/5

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

States a specific verb (claim), the resource (an open action), the actor (this API key), and the observable effect (other agents skip it), plus that it returns the updated action. It is clearly distinguishable from complete_action and dismiss_action, which are named in the same breath.

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

Usage Guidelines5/5

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

Explicit when/when-not: only an open action can be claimed, claiming is optional, and complete_action also accepts an open action. It also routes the agent forward ('Next: change the codebase, then complete_action, or dismiss_action if the finding does not apply').

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

complete_actionComplete an actionA
Idempotent
Inspect

Mark a problem done after you have addressed it in the codebase. Pass note to record what you changed; the owner reads it to tell a real fix from a box ticked. Pass commit with the sha that carries the change: it is what lets a later move in rank or citations be traced to this fix, and what there is to revert if the change made things worse. When one change closed several findings โ€” an edit to a shared layout usually does โ€” pass their ids as actionIds so they close together under that one commit, rather than being recorded as unrelated fixes; get_next_work gives you the set as sameFix.actionIds. Accepts an open or claimed action and returns it with status done; one already done or dismissed answers not_found, so a repeat call changes nothing. If a later audit still measures the problem, a new action is filed. Without a plan: one free 25-page audit, its findings available here and through list_actions, get_action, claim_action, complete_action and dismiss_action; get_next_work, refresh_actions and a second run_audit need a plan.

ParametersJSON Schema
NameRequiredDescriptionDefault
noteNoWhat you changed, in one line. Shown to the owner alongside the finding.
commitNoThe commit that carries the change, so the fix can be traced and reverted.
actionIdYesAction id (a UUID) from the id field of a list_actions row, an exampleActionIds entry of a group, or get_next_work
actionIdsNoFurther findings the same change closed. Only include what this commit actually fixed; ids that are not open findings of this project come back in notFound.
projectIdYesProject id (a UUID) from add_project or list_projects, e.g. "0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30"

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
noteYesWhy the agent closed this: required on dismissal, optional on completion
typeYesCategory of problem
titleYes
doneAtYes
statusYes
payloadYesEvidence; shape varies by type
notFoundNoactionIds that named no open finding of this project: already closed, or not ours
priorityYes1 is most urgent, 5 least
claimedAtYes
commitShaYesThe commit the agent reported when completing this, if it reported one
createdAtYesWhen the action was filed as an ISO 8601 timestamp
projectIdYes
rationaleYesWhat was measured and why it matters
refreshIdYesThe action-list refresh that filed this action, if any
targetUrlYesThe affected URL, if the problem is page-level
updatedAtYesWhen the action last changed as an ISO 8601 timestamp
alsoClosedNoFurther findings closed by this call's actionIds, beyond the one reported here
claimedByApiKeyIdYes

TDQS

A4.6/5.0
Behavior5/5

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

Adds substantial behavior beyond the annotations: it returns the action with status done, answers not_found for already-done/dismissed actions, treats repeat calls as no-ops, records the commit so the fix can be traced or reverted, and files a new action if a later audit still measures the problem. This enriches the idempotentHint=true / destructiveHint=false annotations with concrete consequences rather than restating them.

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

Conciseness4/5

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

The primary action is front-loaded and each sentence about note/commit/actionIds earns its place by explaining why the argument matters. The closing sentence about free audits and plan-gated tools (get_next_work, refresh_actions, a second run_audit) is tangential boilerplate for this specific tool and dilutes focus.

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

Completeness5/5

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

For a mutation tool with an output schema, the description covers the mutation's effect, error states (not_found, notFound), idempotency, grouping semantics, plan gating, and where the input ids come from. Nothing an agent needs in order 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.

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3, but the description adds real meaning: note is read by the owner to tell a genuine fix from a box ticked, commit is what makes the fix traceable and revertable, and actionIds groups co-closed findings under one commit rather than recording unrelated fixes. It also documents the notFound behavior for invalid actionIds, which the schema only hints at.

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

Purpose5/5

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

States a specific verb and resource with scope: "Mark a problem done after you have addressed it in the codebase," and explicitly distinguishes the resulting status from siblings such as dismiss_action and claim_action by naming the done/dismissed states. An agent can tell exactly what this does and how it differs from the other action-lifecycle tools.

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

Usage Guidelines4/5

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

Gives a clear trigger (after addressing the issue in code) and routes the agent to get_next_work for the sameFix.actionIds set. It notes the not_found outcome for actions already done or dismissed but never explicitly frames dismiss_action as the alternative when no fix was made, so the when-not case 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.

dismiss_actionDismiss an actionA
Idempotent
Inspect

Drop a problem you are deliberately not acting on, and say why. reason is required and is shown to the site owner: explain what makes this finding wrong or inapplicable here, in a sentence they could disagree with. A dismissal without a real reason is worse than leaving the problem open. Accepts an open or claimed action and returns it with status dismissed; later refreshes do not file the same finding again. One already done or dismissed answers not_found. Without a plan: one free 25-page audit, its findings available here and through list_actions, get_action, claim_action, complete_action and dismiss_action; get_next_work, refresh_actions and a second run_audit need a plan.

ParametersJSON Schema
NameRequiredDescriptionDefault
reasonYesWhy this finding does not apply to this site, in your own words. Shown to the owner, so a bare 'not applicable' is not useful.
actionIdYesAction id (a UUID) from the id field of a list_actions row, an exampleActionIds entry of a group, or get_next_work
projectIdYesProject id (a UUID) from add_project or list_projects, e.g. "0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30"

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
noteYesWhy the agent closed this: required on dismissal, optional on completion
typeYesCategory of problem
titleYes
doneAtYes
statusYes
payloadYesEvidence; shape varies by type
notFoundNoactionIds that named no open finding of this project: already closed, or not ours
priorityYes1 is most urgent, 5 least
claimedAtYes
commitShaYesThe commit the agent reported when completing this, if it reported one
createdAtYesWhen the action was filed as an ISO 8601 timestamp
projectIdYes
rationaleYesWhat was measured and why it matters
refreshIdYesThe action-list refresh that filed this action, if any
targetUrlYesThe affected URL, if the problem is page-level
updatedAtYesWhen the action last changed as an ISO 8601 timestamp
alsoClosedNoFurther findings closed by this call's actionIds, beyond the one reported here
claimedByApiKeyIdYes

TDQS

A4.3/5.0
Behavior5/5

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

Goes well beyond the annotations: it discloses that the reason is user-visible to the site owner, that a low-quality reason is worse than leaving the problem open, the state transition (returns the action with status dismissed), the durable effect (later refreshes do not refile the finding), and the not_found error path. With annotations only covering safety/idempotency, this is rich behavioral disclosure.

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

Conciseness4/5

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

Front-loads the purpose and the reason requirement, then layers consequences and error behavior efficiently. The trailing plan/tier sentence is somewhat tangential to invoking the tool and lengthens the definition, but it is not wasted context.

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

Completeness4/5

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

For a mutation with a small schema, the description covers trigger conditions, side effects, and error responses, and the plan-gating constraint. An output schema exists so return-value explanation is not required, and the remaining gap (auth requirements, handled by how_to_authenticate) is minor.

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

Parameters3/5

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

Schema description coverage is 100%, so all three parameters including the min/max length and the owner-visible framing of `reason` are already documented. The description reinforces the importance of a substantive reason but adds no format, syntax, or sourcing detail beyond the schema, matching the baseline of 3.

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

Purpose5/5

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

States a specific verb and resource ('Drop a problem you are deliberately not acting on') and immediately distinguishes the operation from acting on it, which separates it from complete_action/claim_action. The follow-on sentence clarifies the required artifact (the reason) and the resulting state.

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

Usage Guidelines4/5

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

Gives clear context for when to dismiss (a finding you are deliberately not acting on) and clarifies edge behavior: an already done or dismissed action returns not_found, and refreshes won't refile the finding. It names the related tools (list_actions, get_action, claim_action, complete_action) but does not explicitly say 'use complete_action instead when the issue is real', so the sibling contrast is implicit rather than spelled out.

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

geo_summaryGEO visibility summaryA
Read-onlyIdempotent
Inspect

Returns how often the site appears in AI answers: one row per tracked prompt, and within it one entry per engine with runs, citedRuns, mentionedRuns, citedRate and mentionedRate, plus the competitor domains cited instead, over the last days. Read-only. Frequency over the window is the metric: there is never a per-run rank, and engines are never blended. An empty array means no prompts (add_geo_prompts); runs of 0 mean nothing measured in the window yet (check_geo). Fewer than three runs on an engine is too few to call a gap. Pass view: "full" for the competitor URLs and the fan-out queries the engine issued behind each prompt; that payload is per prompt per engine and grows past what fits in a context window, which is why it is not the default.

ParametersJSON Schema
NameRequiredDescriptionDefault
daysNoWindow in days, counted back from now, 1-365; default 30, e.g. 90 for a quarter
viewNobrief (the default) is the rates and the top competitor domains. full adds the competitor URLs and fan-out queries per engine, which is far larger.
projectIdYesProject id (a UUID) from add_project or list_projects, e.g. "0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30"

TDQS

A4.4/5.0
Behavior5/5

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

With readOnly/idempotent/non-destructive already covered by annotations, the description adds real behavioral context: frequency-over-window is the metric, there is never a per-run rank, engines are never blended, fewer than three runs is too few to call a gap, and view:"full" can exceed a context window. These are non-obvious constraints an agent cannot infer from annotations.

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

Conciseness4/5

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

Front-loaded with the core purpose and return shape before dipping into edge-case semantics. It is dense and mostly earns its length, though it restates the view:"full" payload tradeoff that the schema already carries, making it slightly longer than strictly necessary.

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

Completeness5/5

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

There is no output schema, so the description carries the full burden of explaining the return payload, and it does so field-by-field (runs, citedRuns, mentionedRuns, citedRate, mentionedRate, competitor domains). Combined with interpretation rules for empty and zero-run results, an agent has everything needed to call and read it correctly.

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

Parameters3/5

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

Schema description coverage is 100%, so days, view, and projectId are already fully documented with ranges, enum values, and defaults. The description reinforces view semantics (why full is not default) but adds no syntax or format detail beyond the schema, so the baseline 3 applies.

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

Purpose5/5

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

States a specific verb+resource (returns GEO visibility in AI answers) and precisely describes the return shape: one row per tracked prompt, one entry per engine with runs/citedRuns/mentionedRuns/citedRate/mentionedRate plus competitor domains. It explicitly differentiates itself from siblings by referencing add_geo_prompts and check_geo for the empty/zero cases.

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

Usage Guidelines4/5

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

Routing guidance is present for the common edge cases: an empty array routes to add_geo_prompts, zero runs routes to check_geo. It also tells the agent when to pass view:"full" (competitor URLs and fan-out queries) versus the default. It lacks an explicit statement of the primary 'use this when you want X' trigger, but the conditionality it does provide is concrete.

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

get_actionGet an actionA
Read-onlyIdempotent
Inspect

Returns one action in full: type, priority, title, rationale (what was measured and why it matters), targetUrl, status, the claim and closing fields, and payload, the evidence (the audit rule id and its measured values, such as the current title and its length; the shape varies by type). Read-only. Use it on the one action you are about to work on; list_actions and get_next_work are for choosing. An id that is not an action of this project answers not_found. It states the problem, never the fix. Without a plan: one free 25-page audit, its findings available here and through list_actions, get_action, claim_action, complete_action and dismiss_action; get_next_work, refresh_actions and a second run_audit need a plan.

ParametersJSON Schema
NameRequiredDescriptionDefault
actionIdYesAction id (a UUID) from the id field of a list_actions row, an exampleActionIds entry of a group, or get_next_work
projectIdYesProject id (a UUID) from add_project or list_projects, e.g. "0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30"

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
noteYesWhy the agent closed this: required on dismissal, optional on completion
typeYesCategory of problem
titleYes
doneAtYes
statusYes
payloadYesEvidence; shape varies by type
notFoundNoactionIds that named no open finding of this project: already closed, or not ours
priorityYes1 is most urgent, 5 least
claimedAtYes
commitShaYesThe commit the agent reported when completing this, if it reported one
createdAtYesWhen the action was filed as an ISO 8601 timestamp
projectIdYes
rationaleYesWhat was measured and why it matters
refreshIdYesThe action-list refresh that filed this action, if any
targetUrlYesThe affected URL, if the problem is page-level
updatedAtYesWhen the action last changed as an ISO 8601 timestamp
alsoClosedNoFurther findings closed by this call's actionIds, beyond the one reported here
claimedByApiKeyIdYes

TDQS

A4.6/5.0
Behavior5/5

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

Annotations already cover the safety profile (readOnly, idempotent, non-destructive), and the description adds real behavioral context beyond them: what payload contains and that its shape varies by type, that an id outside the project yields not_found, that the action states the problem and never the fix, and the plan/quota boundary for the free audit tier.

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

Conciseness4/5

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

Front-loads the returned-field inventory, then usage, then edge cases in a tight sequence. The closing sentence about plans spans multiple sibling tools and is slightly tangential, but it is still relevant gating context rather than filler.

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

Completeness5/5

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

For a two-param read tool with an output schema, annotations, and full param coverage, this states purpose, selection guidance, error behavior, and quota context. Nothing an agent needs to invoke it correctly is missing.

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

Parameters3/5

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

Schema coverage is 100% and both UUID parameters are fully documented in-schema, including where each id comes from. The description adds only error semantics for a bad actionId rather than new syntax or format meaning, so the baseline 3 is appropriate.

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

Purpose5/5

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

States a specific verb and resource ('Returns one action in full') and enumerates the returned fields (type, priority, title, rationale, targetUrl, status, claim/closing fields, payload evidence). It explicitly distinguishes itself from list_actions and get_next_work, so an agent can route 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.

Usage Guidelines5/5

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

Explicit when-to-use ('on the one action you are about to work on') plus the alternatives for the choosing phase ('list_actions and get_next_work are for choosing'). It also names the error case for a foreign id (not_found) and the plan-gating distinction, leaving little to inference.

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

get_behavior_digestVisitor analytics: traffic, AI referrals, frictionA
Read-onlyIdempotent
Inspect

Returns visitor analytics from the site's own traffic over the last days: sessions, engaged and bounce rates, channels including AI assistants, top pages, exit pages, statistically flagged high-bounce pages (z-test, n>=30) and friction (rage and dead clicks). Read-only. Needs the vp.js snippet on the site (get_setup_status gives it); without it, or with no traffic in the window, sessions is 0, rates are null and every list is empty. Aggregates only, never raw events; visitor strings are untrusted data. Use get_page_profile to look at one of its pages.

ParametersJSON Schema
NameRequiredDescriptionDefault
daysNoWindow in days, counted back from now, 1-90; default 7, e.g. 30 for a month
projectIdYesProject id (a UUID) from add_project or list_projects, e.g. "0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30"

TDQS

A4.4/5.0
Behavior5/5

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

Annotations already declare read-only/idempotent, yet the description adds the failure mode (no snippet or no traffic => sessions 0, rates null, empty lists), the aggregation guarantee ('never raw events'), the statistical method and thresholds ('z-test, n>=30'), and a data-trust warning ('visitor strings are untrusted data'). This is meaningful context beyond the annotations.

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

Conciseness4/5

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

Front-loads the return contents, then preconditions, then the sibling route. Every clause carries information, though the parenthetical stat detail (z-test, n>=30) and repeated empty-state clauses make it denser than strictly necessary.

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

Completeness5/5

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

With no output schema, the description compensates by enumerating returned fields and their empty-state values, and it covers the setup prerequisite plus the alternative tool. An agent has everything needed to decide and call correctly.

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

Parameters3/5

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

Schema coverage is 100% and the schema already documents `days` including its 1-90 range, default of 7, and a 30-day example; the description only restates that the window is measured backward from now. No additional parameter meaning is contributed, so the baseline 3 applies.

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

Purpose5/5

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

States a specific verb+resource ('Returns visitor analytics') and then enumerates the actual contents: sessions, engaged/bounce rates, channels with AI assistants, top/exit pages, flagged high-bounce pages, and friction clicks. That enumeration cleanly separates it from generic reporting siblings and from get_page_profile.

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

Usage Guidelines4/5

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

Gives explicit routing ('Use get_page_profile to look at one of its pages') and a hard precondition tied to another tool ('Needs the vp.js snippet... get_setup_status gives it'). It does not differentiate against other analytics siblings such as get_site_health or get_page_history, so it stops short of full when-not guidance.

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

get_content_briefEvidence for one queryA
Read-onlyIdempotent
Inspect

Evidence for building a page for one query. Contains no wording; what to write is yours. query is one row's query from list_opportunities, exactly as it came back (a tracked keyword, a tracked prompt, or a fan-out sub-question); anything else answers not_found. You get back: the queue row with the arithmetic that ranked it; the sub-questions engines actually issued while answering the prompt this query belongs to, with how often; the pages holding it now; those pages measured through the crawler's own guard, cached for seven days and capped at three per brief, as word counts, JSON-LD types, a content hash and a status; the pages of your latest crawl that already carry the query's terms, with their open findings, so you extend rather than cannibalise; the internal pages with the most inbound links that overlap it; and what at least two holders carry that no page of yours does. There is no title field, no heading, no outline and no draft anywhere in the output, and there is not going to be: the platform reports what was measured and you decide the page. Requires the profile: call set_project_profile first.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYesA query from list_opportunities, copied exactly (case and spacing are normalised)
projectIdYesProject id (a UUID) from add_project or list_projects, e.g. "0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30"

Output Schema

ParametersJSON Schema
NameRequiredDescription
queryYesThe tracked query this brief is about, as it is stored
holdersYesThe pages holding this query now
missingYes
evidenceYes
linkFromYesThe site's own pages with the most inbound internal links that overlap the query
holderPagesYesThose pages as measured through the crawler's own guard, cached for 7 days, at most three per brief. Counts, types, a hash and a status; never their text.
opportunityYesThe queue row for this query
existingPagesYesPages of the latest crawl that already speak to this query
wordCountBandYesMin and max word count across the measured holder pages
questionsToAnswerYesSub-questions the engines actually issued while answering the prompt(s) this query belongs to, seen at least twice. Measured, not generated.

TDQS

A4.5/5.0
Behavior5/5

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

Annotations already declare read-only, idempotent, non-destructive, closed-world behaviour, and the description adds substantial context beyond them: measurement is cached for seven days, capped at three pages per brief, the profile must be set beforehand, invalid queries return not_found, and the output deliberately contains no title, heading, outline or draft. This is exactly the kind of non-obvious behavioural detail the annotations cannot carry.

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

Conciseness3/5

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

Purpose and prerequisites are front-loaded, but the middle is a single sprawling sentence enumerating every element of the return payload, which is largely redundant because an output schema already exists. The prose is dense and readable, yet that enumeration is length the definition does not need to pay for.

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

Completeness5/5

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

For a read tool with full annotation coverage, a complete schema and an output schema, the description supplies everything an agent needs: the precondition, the valid input source, the failure mode, the caching and capping limits, and the deliberate absence of generative content. No gaps remain that would cause a wrong invocation.

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

Parameters4/5

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

Schema coverage is 100% and both parameters are documented in the schema, so the baseline would be 3. The description goes further on the query parameter, explaining that it must be a tracked keyword, tracked prompt, or fan-out sub-question copied exactly as returned, which adds real selection meaning beyond the schema's normalisation note.

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

Purpose5/5

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

States a specific resource (the evidence bundle for one query) and its exact scope: the queue row's arithmetic, sub-questions engines issued, current holders, the caller's own pages, internal link overlaps, and gaps. It also distinguishes itself from list_opportunities by naming that tool as the source of valid input, so an agent can tell the two apart 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.

Usage Guidelines4/5

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

Gives explicit prerequisites ('call set_project_profile first') and a precise input-sourcing rule: the query must be one row's query from list_opportunities copied exactly, otherwise the tool answers not_found. It does not state any when-not-to-use case against alternatives, but the routing and precondition guidance is concrete.

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

get_next_workWhat to do nextA
Read-onlyIdempotent
Inspect

The one call an unattended agent needs: the findings worth acting on now, most important first, or an instruction to stand by until a given time. Ordering is severity weighted by the page's own measured traffic. Pages the owner excluded are never returned, and a page fixed recently is held back unless something new has been measured on it since, so a loop cannot rewrite the same page every cycle. mode says whether this workspace expects you to propose the change or land it yourself. Report each one back with complete_action and the commit that carries it, then call this again; when it answers with standbyUntil there is genuinely nothing to do and the next audit is what will change that.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoHow many to take on now. Defaults to 5.
projectIdYesProject id (a UUID) from add_project or list_projects, e.g. "0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30"

Output Schema

ParametersJSON Schema
NameRequiredDescription
modeYesWhat this workspace expects you to do with a fix: propose leaves the change for a human to accept, commit means land it yourself.
itemsYesWhat to work on now, most important first, one entry per kind of finding rather than one per finding. Empty when there is nothing to do.
remainingYesOpen findings not covered by these entries; call again when done with them
standbyUntilYesISO time to sleep until, set only when there is nothing to do. The next scheduled audit is what produces new findings.
quotaWarningsYesMetrics this workspace will spend before the month resets, at the current rate. Nothing breaks when one runs out: the scheduled audits stop until it resets. Tell the owner rather than working around it.
withheldByCooldownYesFindings held back because their page was fixed recently and nothing new has been measured on it since

TDQS

A4.5/5.0
Behavior5/5

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

Goes well beyond the readOnly/idempotent annotations by disclosing the ordering rule (severity weighted by measured traffic), the exclusion of owner-excluded pages, the anti-loop hold-back on recently fixed pages, and the meaning of `mode`. These are exactly the behaviors an agent needs to trust the output.

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

Conciseness4/5

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

Front-loaded with the core purpose and scoped tightly to what the agent needs, but the final sentence is dense and carries three distinct flow instructions (report back, re-call, standby semantics) that could be split.

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

Completeness4/5

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

Given an output schema exists, return values need not be re-explained, yet the description still clarifies standbyUntil and mode. It is complete for invoking the tool; only minor operational detail (e.g. how limit interacts with the loop) is left implicit.

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

Parameters3/5

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

Schema description coverage is 100%, so the schema already documents projectId and limit. The description adds the meaning of `mode`, but that is an output field rather than a parameter, so it does not enrich the documented inputs beyond the schema baseline.

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

Purpose5/5

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

States a concrete verb and resource with scope: the prioritized findings worth acting on now, or a standby instruction. It is clearly differentiated from sibling listers (list_actions, list_opportunities) by being the severity-ordered, loop-aware answer to 'what next'.

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

Usage Guidelines5/5

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

Explicitly frames the operating loop: call this, act, report back with complete_action and the commit, then call again; a standbyUntil answer means nothing is actionable. It names the sibling (complete_action) and the condition for re-invocation.

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

get_page_historyOne page over timeA
Read-onlyIdempotent
Inspect

Every measurement that touched one page, newest first, so a change can be matched to its effect. url is the full url of a page on the tracked site (https://example.com/guide); days defaults to 90. Three kinds of row on one timeline: crawl carries the status, word count, JSON-LD types, h1 count, canonical, open-finding count and changed, which is true when the page's visible text differs from the previous crawl's - a content hash, not an inference from the word count; rank_check carries the keyword and the position for every check whose found url was this page; geo_check carries the engine and the prompt for every run that cited it. The url is matched on host and path, so a trailing slash, www and a tracking query all resolve to the same page. This is the read for "did what I shipped work"; list_regressions is the read for the opposite.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYesFull url of one page, e.g. https://example.com/guide
daysNoWindow in days, default 90
projectIdYesProject id (a UUID) from add_project or list_projects, e.g. "0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30"

Output Schema

ParametersJSON Schema
NameRequiredDescription
urlYesThe page the timeline is for, as it was asked for
daysYesWindow the timeline covers
eventsYesOne row per measurement, newest first

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already cover the read-only/idempotent safety profile, yet the description adds substantial behavior: the three row kinds (crawl, rank_check, geo_check), the precise meaning of `changed` as a content hash rather than a word-count inference, and the URL normalization rule (host+path, trailing slash, www, tracking query). This is exactly the extra context annotations cannot carry.

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

Conciseness4/5

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

It is a long description, but it is front-loaded with the core purpose and every sentence carries information (row types, change semantics, URL matching, sibling routing). Slightly dense, yet nothing reads as filler.

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

Completeness5/5

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

With annotations, full schema coverage, and an output schema present, the description need not explain return values, and it still supplies the row-type taxonomy and matching semantics an agent needs. Nothing required 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.

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3, but the description goes beyond the schema by explaining that the url is matched on host and path and how trailing slashes, www, and tracking queries all resolve to the same page. That normalization behavior is not derivable from the schema and materially affects how the parameter should be supplied.

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

Purpose5/5

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

States a specific verb and resource ('Every measurement that touched one page, newest first') and immediately frames the intent as matching a change to its effect. It clearly distinguishes itself from sibling reads like rank_history, get_page_profile, and list_regressions.

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

Usage Guidelines5/5

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

Explicitly names the use case ('did what I shipped work') and the contrasting alternative ('list_regressions is the read for the opposite'), giving the agent a direct routing rule. No ambiguity about when this tool is the right choice versus its siblings.

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

get_page_profilePage behavior profileA
Read-onlyIdempotent
Inspect

Returns the visitor behaviour of one page over the last days: pageviews, entries, bounce rate, exits, 50% and 100% scroll rates, average active time, rage and dead clicks, and vsSite, a two-proportion z-test of its bounce rate against the rest of the site (only meaningful with at least 30 entries on each side). Read-only. Needs the vp.js snippet; take the path from get_behavior_digest's topPages. A path with no recorded traffic returns zero counts and null rates, not an error.

ParametersJSON Schema
NameRequiredDescriptionDefault
daysNoWindow in days, counted back from now, 1-90; default 7
pathYesPage path exactly as recorded, e.g. "/pricing": no scheme, host or query string (query strings are dropped when visits are recorded). "/pricing" and "/pricing/" are different pages, so copy the path from get_behavior_digest
projectIdYesProject id (a UUID) from add_project or list_projects, e.g. "0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30"

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already cover readOnly/idempotent/non-destructive, but the description adds meaningful context beyond them: the vp.js dependency and, importantly, that a path with no recorded traffic returns zero counts and null rates rather than an error. That edge-case disclosure genuinely reduces misuse; only the vsSite sample-size caveat goes further.

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

Conciseness4/5

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

Front-loaded with the return contract, then prerequisites and the empty-path edge case. The metric enumeration is long but each item is substantive; the only slight drag is the dense one-sentence metric list before the actionable guidance.

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

Completeness4/5

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

No output schema exists, so the description carries the return-value burden and does so by listing the metrics and the null-vs-zero behavior. Prerequisites and the vsSite significance threshold are covered; detail on ordering, aggregation caveats, or response shape beyond the metric list is absent.

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

Parameters3/5

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

Schema coverage is 100%, so the schema already documents days, path and projectId in detail (including the trailing-slash distinction). The description restates days and gestures at path but adds no format or syntax detail beyond the schema, so the baseline 3 applies.

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

Purpose5/5

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

States a specific verb+resource: it returns visitor behaviour metrics for one page over a window. It enumerates the actual metrics (pageviews, bounce rate, scroll rates, rage/dead clicks) plus the vsSite test, which clearly separates it from siblings like get_behavior_digest (which surfaces topPages) and get_page_history.

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

Usage Guidelines4/5

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

Gives a clear prerequisite (needs the vp.js snippet) and an explicit sourcing instruction: take the path from get_behavior_digest's topPages. It also warns of the exact-path requirement indirectly. It stops short of stating when to prefer an alternative tool or when the call is meaningless (beyond the 30-entry note for vsSite).

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

get_project_profileRead the site's profileA
Read-onlyIdempotent
Inspect

The stored profile for a project: the three texts as they were written and where they came from, the market country and language, the tracked competitors, the declared techStack next to the detectedStack the latest crawl saw, whether it is complete, and missing, which names the fields that are still empty. Call it before list_opportunities to see whether set_project_profile is needed.

ParametersJSON Schema
NameRequiredDescriptionDefault
projectIdYesProject id (a UUID) from add_project or list_projects, e.g. "0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30"

Output Schema

ParametersJSON Schema
NameRequiredDescription
missingYesProfile fields still empty; the strategy tools refuse while this is non-empty
audienceYesWho buys it
completedYestrue once productSummary, valueProposition and audience are all filled in
projectIdYes
techStackYesWhat the site is built with, as declared; the audit prefers it over detectedStack
competitorsYesTracked competitor hostnames, at most 5
completedAtYes
detectedStackYesWhat the latest crawl recognised from the HTML, or null when nothing matched
marketCountryYesTwo-letter country the checks are run for, e.g. us
profileSourceYesWhere the texts came from, when the owner did not write them
marketLanguageYesTwo-letter language, e.g. en
productSummaryYesWhat the product is, as the customer wrote it
valuePropositionYesWhy someone picks it

TDQS

A3.6/5.0
Behavior3/5

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

Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and openWorldHint=false, so the safety and idempotency profile is fully covered. The description adds the semantic of `missing` (naming empty fields) and a completeness flag, which is useful context, but says nothing about freshness, auth needs, or caching beyond what annotations provide.

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

Conciseness3/5

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

The usage sentence is tight and earns its place, but the first sentence is a long comma-chained enumeration of return fields that largely duplicates the existing output schema. It is front-loaded with content rather than with a statement of what the tool does.

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

Completeness4/5

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

With an output schema present, the description needn't explain return values, yet it does so thoroughly and adds the workflow hook into list_opportunities/set_project_profile. Nothing needed to invoke the tool correctly is absent.

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

Parameters3/5

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

Only one parameter exists and the schema documents it at 100% coverage (UUID format, pattern, and provenance 'from add_project or list_projects'). The description adds no parameter meaning, which is acceptable but not additive โ€“ baseline 3 applies.

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

Purpose4/5

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

The description enumerates exactly what the stored profile contains (three texts and their provenance, market country/language, tracked competitors, declaredStack vs detectedStack, completeness, and `missing`), and says 'for a project', which separates it from the sibling get_page_profile. It never states an explicit retrieval verb itself, leaning on the title for that, so it stops just short of a 5.

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

Usage Guidelines4/5

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

It gives concrete routing: 'Call it before list_opportunities to see whether set_project_profile is needed' names both the ordering constraint and the sibling tool that may follow. There is no explicit when-not condition, but the trigger and alternative are unambiguous.

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

get_setup_statusOnboarding checklistA
Read-onlyIdempotent
Inspect

The onboarding as a checklist for one project: each step (profile, tech stack, competitors, first audit, keywords, rank check, GEO prompts, GEO check, visitor snippet) with whether it is done, what it needs and the tool that completes it, plus next, the first step still open. Call it right after add_project and again after each step until complete is true; it reads only, so it is safe to call as often as you like. An unknown projectId answers not_found.

ParametersJSON Schema
NameRequiredDescriptionDefault
projectIdYesProject id (a UUID) from add_project or list_projects, e.g. "0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30"

Output Schema

ParametersJSON Schema
NameRequiredDescription
nextYesThe first step still open; call its tool
planYesThe workspace plan; "none" is the free preview, where only run_audit runs
stepsYes
domainYes
completeYes
projectIdYes

TDQS

A4.6/5.0
Behavior4/5

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

Annotations already declare readOnly/idempotent/non-destructive, so the safety profile is covered; the description reinforces it with 'reads only, so it is safe to call as often as you like,' which is mostly redundant. The genuinely additive clause is the failure behavior: 'An unknown projectId answers not_found,' which no annotation discloses.

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

Conciseness4/5

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

Front-loaded with purpose, then usage cadence, then error behavior; every clause carries information. The first sentence is long due to the nine-step enumeration, but that enumeration is load-bearing rather than padding.

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

Completeness5/5

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

With only one fully documented parameter, an output schema present, and rich annotations, the description supplies everything else an agent needs: invocation cadence, stop condition, what the response structure looks like, and the not_found case.

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

Parameters4/5

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

Schema coverage is 100% and the schema already documents projectId as a UUID with an example and its source (add_project / list_projects), so the baseline is 3. The description adds invalid-value semantics โ€” an unknown projectId returns not_found โ€” which is real parameter-level information beyond the schema.

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

Purpose5/5

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

The description names a specific resource (the onboarding checklist for one project) and enumerates exactly what each step entry contains โ€” done state, requirements, and the completing tool โ€” plus the `next` pointer. It is clearly distinguishable from siblings like get_next_work or get_action because it is scoped to the onboarding flow.

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

Usage Guidelines5/5

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

It states explicit timing: 'Call it right after add_project and again after each step until `complete` is true.' The loop-termination condition is given, and the chapter names the sibling entry point (add_project) that precedes it, leaving nothing to inference.

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

get_site_healthSite healthA
Read-onlyIdempotent
Inspect

Returns the project's current state: the latest crawl (status, pages crawled, when), issue counts by severity and by rule, the open action count and the scores, where a dimension with no data yet is null rather than 0. Read-only. Call it after run_audit to see whether the crawl finished, and before list_actions for the overview. With no crawl yet latestCrawl is null and the counts are 0: call run_audit. Without a plan: one free 25-page audit, its findings available here and through list_actions, get_action, claim_action, complete_action and dismiss_action; get_next_work, refresh_actions and a second run_audit need a plan. There the answer also carries freeAudit: the audit's outcome and a next line naming the tools that reach its findings; until the free audit has finished it is the preview instead (preview=true, the state, and freeAudit.next).

ParametersJSON Schema
NameRequiredDescriptionDefault
projectIdYesProject id (a UUID) from add_project or list_projects, e.g. "0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30"

TDQS

A4.3/5.0
Behavior4/5

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

Annotations already cover the safety profile (readOnly, idempotent, non-destructive, closed world), but the description adds meaningful semantics beyond that: null-versus-0 for dimensions with no data, the free 25-page audit entitlement, and the conditional freeAudit/preview payload. It stops short of describing pagination or field-by-field return detail, but that is minor here.

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

Conciseness3/5

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

Front-loaded with the return contents, but the prose is dense and run-on, especially the plan/free-audit sentences listing five sibling tools inline and the nested 'until the free audit has finished it is the preview instead' clause. The information is useful but the packaging is heavier than needed.

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

Completeness5/5

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

There is no output schema, so the description must carry return semantics, and it does: nulls vs zeros, severity/rule counts, scores, and the freeAudit/preview conditional shape. Combined with the plan-gating note, an agent has what it needs to call and interpret the result.

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

Parameters3/5

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

Only one parameter (projectId) with 100% schema description coverage, so the schema already documents source (add_project/list_projects) and format. The description adds nothing about the parameter, which is the expected baseline when the schema carries the load.

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

Purpose5/5

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

States a specific verb and resource ('Returns the project's current state') and then enumerates the exact payload: latest crawl status/pages/timestamp, issue counts by severity and by rule, open action count and scores. An agent can distinguish this overview tool from list_actions, get_action, or run_audit 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.

Usage Guidelines5/5

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

Explicit sequencing guidance: call it after run_audit to check crawl completion and before list_actions for the overview. It also spells out the no-crawl case (latestCrawl null, counts 0, call run_audit) and the plan/no-plan branch, naming which sibling mutations require a plan.

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

how_to_authenticateGetCited is not authenticatedA
Read-onlyIdempotent
Inspect

This server is not authenticated, so none of its SEO tools will answer. Call this for the exact steps to fix it. Retrying other tools will not help.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.7/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint. The description adds contextual behavior: the server is unauthenticated, causing all other tools to fail, and this tool returns the fix steps. It also warns that retrying others is futile, which is valuable beyond the structured hints.

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

Conciseness5/5

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

The description is two sentences with zero fluff. It front-loads the core problem ('This server is not authenticated'), then gives the action ('Call this for the exact steps'), and ends with a preventive note. Every sentence earns its place.

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

Completeness5/5

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

Given the tool has no parameters, no output schema, and annotations covering safety, the description fully covers what an agent needs: the reason for the tool's existence, when to use it, and what it returns. Nothing essential is missing.

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

Parameters4/5

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

There are zero parameters, and schema coverage is trivially 100%. The baseline for no parameters is 4, and the description adds nothing about parameters because none exist. No further explanation is needed.

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

Purpose5/5

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

The description states the tool's exact purpose: to provide steps to fix authentication for the server. It clearly differentiates itself from siblings by noting that all other SEO tools will not answer and that this is the remedy. The verb is implicit but strong ('Call this'), and the resource is specific ('exact steps to fix it').

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

Usage Guidelines5/5

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

The description explicitly tells the agent when to call it ('Call this for the exact steps to fix it') and what not to do ('Retrying other tools will not help'). It conveys that this tool is the only path when authentication is the issue, which is clear guidance for selection among the many siblings.

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

list_actionsList actionsA
Read-onlyIdempotent
Inspect

Returns the prioritized problems filed for a project, most urgent first; priority 1 is most urgent, 5 least. Read-only. Defaults to open ones. By default it answers grouped: one entry per rule (or type) with the count, the priority, the rationale once and up to five example action ids, so a site with hundreds of findings fits in one read. Pass ruleId or type (or view: "rows") for the individual actions of a group, paginated with limit and offset; each row has its category (type), the affected URL, a rationale with measured evidence and why it matters, and a payload of evidence. verbose adds bookkeeping fields (run id, claiming key, timestamps). An empty answer for status open means nothing is filed: run run_audit (or refresh_actions after new rank or GEO data). Use get_action for one row in full, get_next_work to be told what to take next. Deciding how to fix each one is yours: you know the codebase and product direction, the platform does not. Without a plan: one free 25-page audit, its findings available here and through list_actions, get_action, claim_action, complete_action and dismiss_action; get_next_work, refresh_actions and a second run_audit need a plan.

ParametersJSON Schema
NameRequiredDescriptionDefault
typeNoOnly actions of this category
viewNogrouped (default) or rows; rows is the default when ruleId or type is given
limitNoRows per page, default 50
offsetNoRows to skip, from nextOffset
ruleIdNoOnly actions filed from this audit rule, e.g. missing_title (a group's key)
statusNoWhich actions to return; default open. open: not yet taken; claimed: taken by an agent with claim_action; done: closed with complete_action; dismissed: closed with dismiss_action and a reason
verboseNoInclude bookkeeping fields on each row; default false
projectIdYesProject id (a UUID) from add_project or list_projects, e.g. "0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30"

Output Schema

ParametersJSON Schema
NameRequiredDescription
viewYes
totalYesActions matching the status and filters
groupsNoThe grouped view
offsetNo
statusYes
actionsNoThe rows view, one page
nextOffsetNoPass as offset for the next page; null on the last one
priorityScaleYes

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already assert readOnlyHint/idempotent/non-destructive, but the description adds substantial non-structured behavior: defaults to status open, grouping collapses hundreds of findings to one entry per rule with a count and up to five example ids, rows are paginated with limit/offset, verbose adds bookkeeping fields, and free-tier limits are stated. This is well beyond what annotations convey.

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

Conciseness4/5

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

Effectively front-loaded: scope, ordering, default, grouping, then drill-down, then alternatives, then plan constraints. It is dense and long, and the closing billing/plan sentence is somewhat tangential, but nearly every sentence contributes actionable routing or behavior information.

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

Completeness5/5

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

With 8 params fully documented, annotations covering the safety profile, and an output schema for return shape, the description closes the remaining gaps an agent needs: default status, grouping vs rows behavior, pagination, empty-result handling, and sibling hand-offs. Nothing essential to correct invocation is missing.

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

Parameters4/5

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

Schema coverage is 100%, so baseline is 3, but the description adds interaction semantics the schema states only tersely: that supplying ruleId or type switches to per-row output, what each row contains (category, URL, rationale with evidence, payload), and what verbose actually appends. It stops short of documenting limit/offset/enum values, which the schema already carries well.

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

Purpose5/5

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

Opens with a specific verb+resource+ordering ('Returns the prioritized problems filed for a project, most urgent first; priority 1 is most urgent, 5 least'), then explains the grouping default. An agent can distinguish this list tool from get_action and get_next_work 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.

Usage Guidelines5/5

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

Gives explicit routing: pass ruleId/type (or view: rows) for individual actions, use get_action for one row in full, get_next_work to be told what to take next, and run_audit/refresh_actions when an 'open' answer is empty. It also states the plan/prerequisite conditions for get_next_work, refresh_actions and a second run_audit.

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

list_keywordsList keywordsA
Read-onlyIdempotent
Inspect

Returns keywords, one row per tracked keyword, newest first: id (the keywordId rank_history takes), term, country, language, createdAt, metric (search volume, cpc, difficulty, fetchedAt) and rank (latest position within the top 30, null when the site is not in it, foundUrl, checkedAt, and whether an AI Overview appeared and cited the site). Read-only. metric is null until enrichment lands, about ten minutes after add_keywords; rank is null until check_rankings has run and its results have landed. An empty array means no keywords: call add_keywords.

ParametersJSON Schema
NameRequiredDescriptionDefault
projectIdYesProject id (a UUID) from add_project or list_projects, e.g. "0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30"

Output Schema

ParametersJSON Schema
NameRequiredDescription
keywordsYes

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already cover the safety profile (readOnly, idempotent, non-destructive), so 'Read-only' is redundant. The description earns credit for genuinely new behavioral context: metric stays null until enrichment lands (~10 min after add_keywords), rank stays null until check_rankings has run, and an empty array means no keywords.

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

Conciseness4/5

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

The purpose and row shape are front-loaded, followed by the null/timing caveats and the empty-array escape hatch. It is dense but every clause carries information; only the redundant 'Read-only' line is filler.

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

Completeness5/5

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

With a single fully-documented parameter and an output schema present, the description need not restate return values, yet it usefully explains null and empty-result semantics and enrichment latency. 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.

Parameters3/5

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

Schema coverage is 100%, so the projectId parameter and its UUID format/source are already fully documented in the schema. The description adds no additional parameter semantics, making the baseline 3 appropriate.

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

Purpose5/5

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

States a specific verb and resource ('Returns keywords, one row per tracked keyword, newest first') and enumerates the shape of each row, so an agent knows exactly what it gets. It is clearly distinguishable from siblings like add_keywords and check_rankings.

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

Usage Guidelines4/5

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

Gives clear context: use it to read tracked keywords, and it explicitly routes an empty result to add_keywords. It does not state when *not* to use it (e.g. versus rank_history for per-keyword detail), so it falls short of full when/when-not guidance.

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

list_opportunitiesQueries this site does not holdA
Read-onlyIdempotent
Inspect

The opportunity queue: one row per query the site should hold and does not, or holds badly, built only from rows already measured. Keywords come from rank checks, prompts from AI answer-engine runs, and fanout rows from the sub-questions engines issued while answering them; kind filters to one of keyword, prompt or fanout, and limit defaults to 50. Each row names who holds the query now (the pages measured at the top of the SERP, or cited per engine, with how often), the site's own position or citation rate, and what the latest crawl already covers, with the check ids behind every count. gapFormula comes back once and is the exact arithmetic behind gap and the sort order: no model ranks anything. Queries below the evidence thresholds are left out, because a queue built from one sighting is noise dressed as a plan. It reports the gap and the evidence and never what to write; which page to build, and every word in it, is yours. Requires the profile: call set_project_profile first.

ParametersJSON Schema
NameRequiredDescriptionDefault
kindNoReturn only rows of this kind; omit for all three
limitNoRows to return, default 50
projectIdYesProject id (a UUID) from add_project or list_projects, e.g. "0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30"

Output Schema

ParametersJSON Schema
NameRequiredDescription
gapFormulaYesThe exact arithmetic behind gap, and the sort order
windowDaysYesRolling window every count in a row is measured over
opportunitiesYes

TDQS

A3.6/5.0
Behavior4/5

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

Annotations already declare readOnlyHint/idempotentHint/non-destructive, so safety is covered. Beyond that the description discloses behavior the annotations cannot: queries below evidence thresholds are silently excluded, gapFormula is returned exactly once, and the tool deliberately reports evidence without prescriptive recommendations. Only pagination/cost behavior is 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.

Conciseness3/5

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

The core scoping facts are front-loaded, but the paragraph is dense with long multi-clause sentences and rhetorical flourishes ('noise dressed as a plan', 'every word in it, is yours') that consume budget without adding invocation guidance.

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

Completeness4/5

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

An output schema exists, so return shape need not be described, yet the description helpfully explains row contents, the gapFormula, and the evidence-threshold exclusion. Combined with the stated profile prerequisite, this is close to complete for a read-only listing tool; only filtering/pagination limits for large result sets are omitted.

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

Parameters3/5

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

Schema description coverage is 100%, so all three parameters are already documented in the schema, and the description's restatement of kind's enum and limit's default of 50 adds little. It does add conceptual meaning to kind (where keyword, prompt, and fanout rows originate), which is mildly useful but not required.

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

Purpose4/5

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

The first sentence states a specific resource and scope: 'the opportunity queue: one row per query the site should hold and does not.' It also explains where rows come from (rank checks, AI answer-engine runs, sub-question fanout), which materially distinguishes it from siblings like list_keywords or rank_history. It stops short of naming an alternative tool it should be chosen over.

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

Usage Guidelines3/5

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

It gives a real prerequisite ('Requires the profile: call set_project_profile first') and explains the kind filter's purpose, which is genuine usage guidance. However, it never states when to reach for this over list_keywords, list_regressions, or get_content_brief, so the agent must infer the routing itself.

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

list_projectsList projectsA
Read-onlyIdempotent
Inspect

Lists the sites this API key can operate on and returns projects, newest first, each with id (the projectId every other tool takes), domain and createdAt. Read-only. Sites removed with remove_project are not listed, and an empty array means nothing is tracked yet. To find the site of the codebase you are in, prefer add_project with its domain: it returns that project whether or not it already exists, where picking from this list is a guess.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
projectsYes

TDQS

A4.7/5.0
Behavior4/5

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

Annotations already declare readOnly, idempotent and non-destructive, so the safety profile is covered. The description goes further with behavioral detail annotations cannot express: removed sites are excluded, an empty array means nothing is tracked, and results are ordered newest first. Some return detail overlaps the output schema, keeping it from 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.

Conciseness5/5

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

Front-loaded with what it lists and returns, then the routing advice. Every sentence carries distinct information (scope, ordering, fields, exclusions, empty-array semantics, alternative tool) with no filler.

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

Completeness5/5

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

For a zero-parameter read tool with an output schema and rich annotations, the description supplies everything an agent needs: what it returns, the key identifier linking to other tools, exclusion semantics, and when to use a different tool instead.

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

Parameters4/5

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

The tool takes no parameters, so the schema baseline of 4 applies. The description correctly implies no filtering inputs and instead explains the shape of what comes back (id, domain, createdAt).

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

Purpose5/5

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

States a specific verb (lists) and resource (sites this API key can operate on) and scopes the result precisely. It distinguishes itself from siblings by naming remove_project as the exclusion and add_project as the alternative, so an agent can tell them apart without opening schemas.

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

Usage Guidelines5/5

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

Explicitly routes the agent: 'To find the site of the codebase you are in, prefer add_project with its domain.' It gives both the alternative tool and the reason (add_project returns the project whether or not it exists, whereas picking from this list is a guess).

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

list_regressionsWhat went backwardsA
Read-onlyIdempotent
Inspect

What is measurably worse than it was, over the last days (default 30). Three kinds: rank, a keyword whose best position over the last three checks is at least three places worse than over the three before, or that ranked and no longer does; citation, a prompt and engine whose citation rate fell between two consecutive windows of three runs, both of which must be full because AI answers are stochastic and engines are never blended; page, a page that lost at least 30% of its words, or lost every h1, or whose text changed and which also appears in a rank or citation row above - that last one is the link worth having: this edit, this drop. Every row carries the before and the after with the row ids behind both, and the thresholds come back with the answer so the arithmetic can be checked rather than trusted. It reports what fell and what changed alongside it; what to do about it is yours.

ParametersJSON Schema
NameRequiredDescriptionDefault
daysNoWindow in days, default 30
projectIdYesProject id (a UUID) from add_project or list_projects, e.g. "0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30"

Output Schema

ParametersJSON Schema
NameRequiredDescription
thresholdsYesThe exact floors a movement has to clear to be reported
windowDaysYesWindow both halves of every comparison come from
regressionsYesSorted by kind, then by the size of the drop

TDQS

A4.6/5.0
Behavior5/5

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

Annotations already cover safety (readOnly, idempotent, non-destructive), and the description adds substantial operational detail beyond them: stochastic AI answers require full windows, engines are never blended, thresholds are returned so the arithmetic can be checked, and each row carries before/after values with the row ids behind both.

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

Conciseness4/5

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

Front-loaded with the core statement before drilling into the three kinds and the verification rationale. It is dense and runs long with several nested clauses, but nearly every sentence carries distinct information rather than padding.

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

Completeness5/5

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

An output schema exists, so return values need not be restated; the description nonetheless explains the shape of results (before/after, row ids, returned thresholds). Nothing an agent needs to invoke or interpret this tool correctly is missing.

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

Parameters4/5

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

Schema coverage is 100% and both params are documented, so the baseline is 3; the description earns extra by explaining what the `days` window actually governs - consecutive three-check and three-run comparison windows - which the schema's 'Window in days, default 30' does not convey.

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

Purpose5/5

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

States a specific verb+resource ('what is measurably worse than it was, over the last days') and then enumerates the three distinct detection kinds (rank, citation, page), which sharply separates it from forward-looking siblings like list_opportunities and get_next_work.

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

Usage Guidelines4/5

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

The description gives clear context for when this applies - a backward-looking regression sweep over a time window - and even signals the boundary of its remit ('what to do about it is yours'). It does not, however, explicitly name an alternative sibling or state exclusions.

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

rank_historyKeyword rank historyA
Read-onlyIdempotent
Inspect

Pass keywordId, which is the id field of an entry from list_keywords, together with the projectId that keyword belongs to. Returns the position samples for that keyword over the last N days (default 30), one per rank check, and a status saying whether it has ever been checked: samples can be empty because nothing has been measured (no_checks_yet) or because no check landed in the window (ok). Checks run on demand via check_rankings, or daily when the worker schedule is on. Read-only; a position is null when the site was not in the top 30.

ParametersJSON Schema
NameRequiredDescriptionDefault
daysNoHow many days back to sample, default 30
keywordIdYesKeyword id (a UUID) from the id field of list_keywords
projectIdYesProject id (a UUID) from add_project or list_projects, e.g. "0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30"

Output Schema

ParametersJSON Schema
NameRequiredDescription
statusYesno_checks_yet when this keyword has never been rank-checked, so an empty samples list means nothing has been measured; call check_rankings. ok when it has been checked at least once, so an empty samples list means no check landed inside the requested window.
samplesYes

TDQS

A4.4/5.0
Behavior5/5

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

Annotations already cover the read-only/idempotent safety profile, and the description adds genuinely new behavior: the status field's two meanings (no_checks_yet vs ok), the reason samples can be empty, and the interpretation of a null position (site outside top 30). That is exactly the extra context annotations cannot carry.

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

Conciseness4/5

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

Front-loads the key instruction ('Pass keywordId...') and packs a lot of value per sentence. It is a single dense paragraph with output semantics folded in, which is slightly run-on but contains no filler.

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

Completeness5/5

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

For a 3-param read tool with an output schema present, the description still explains the non-obvious return semantics (status values, null positions) and how the data is generated, so nothing an agent needs to call and interpret it correctly is missing.

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

Parameters3/5

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

Schema description coverage is 100% โ€“ the schema already documents keywordId, projectId and days (including its range and default). The description restates the keywordId provenance but adds no syntax or format detail beyond the schema, so baseline 3 applies.

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

Purpose5/5

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

States a specific verb and resource: 'Returns the position samples for that keyword over the last N days, one per rank check.' Combined with 'keyword' scope, an agent can tell this apart from the page-oriented sibling get_page_history without opening either schema.

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

Usage Guidelines4/5

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

Gives real context: it says which ids to supply and how they are obtained (list_keywords, add_project/list_projects), and explains that data is produced by check_rankings on demand or by the daily worker schedule. It does not, however, state explicit exclusions versus siblings like get_page_history.

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

refresh_actionsRebuild the action listAInspect

Rebuilds this project's action list from what is already measured (crawl findings, ranks, AI-engine citations, visitor behavior) by fixed rules: no model, no provider call, no quota. Every crawl already triggers one, so call it only after check_rankings or check_geo results have landed and you want them turned into actions now. It measures nothing new: run run_audit, check_rankings or check_geo first if the data is stale. Runs in the worker within seconds to minutes; this returns once it is queued, so poll list_actions. Returns status (queued or already_queued), jobId and trigger. A second call for the same project within a minute returns already_queued.

ParametersJSON Schema
NameRequiredDescriptionDefault
projectIdYesProject id (a UUID) from add_project or list_projects, e.g. "0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30"

Output Schema

ParametersJSON Schema
NameRequiredDescription
jobIdYesJob id, null when this call was deduplicated into an already-queued run
statusYesqueued when this call created the job. already_queued when the same job for this project was enqueued moments ago and this call was deduplicated: the work is coming and nothing extra was billed.
triggerYesHow the refresh was triggered; always manual over MCP
pollWithYesCall list_actions once the worker has finished the run

TDQS

A4.7/5.0
Behavior5/5

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

Annotations only give readOnly=false, openWorld=false, idempotent=false, destructive=false. The description adds the operational profile the annotations cannot: no model/provider call/quota, worker-side execution in seconds-to-minutes, asynchronous return on queue, poll list_actions for completion, and a one-minute dedup window returning already_queued. That is exactly the extra context an agent needs for a fire-and-poll tool.

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

Conciseness5/5

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

Dense but front-loaded: the core action and its no-model nature come first, then prerequisites, then async semantics and return shape. Each sentence carries distinct information (cost profile, gating, polling, dedup) with no filler.

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

Completeness5/5

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

Covers everything needed for correct invocation: prerequisites, cost/side-effect profile, async contract, polling target, return fields, and dedup behavior. An output schema exists, and the description still names the return fields, so nothing material is left for the agent to guess.

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

Parameters3/5

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

Schema description coverage is 100% and the single projectId parameter is fully documented with format, pattern, and provenance in the schema, so the baseline of 3 applies. The description adds no parameter-level syntax or format beyond what the schema already carries.

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

Purpose5/5

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

States a specific verb+resource ('rebuilds this project's action list') and immediately scopes what it derives from (crawl findings, ranks, citations, behavior) and how (fixed rules, no model). An agent can distinguish it from list_actions, get_next_work, and run_audit 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.

Usage Guidelines5/5

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

Explicit when-to-call: 'only after check_rankings or check_geo results have landed and you want them turned into actions now.' Explicit when-not and alternatives: 'It measures nothing new: run run_audit, check_rankings or check_geo first if the data is stale.' Also notes that every crawl already triggers one, discouraging redundant calls.

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

remove_projectStop tracking a siteA
DestructiveIdempotent
Inspect

Stop tracking a site: it leaves list_projects, stops being crawled or checked, and frees a site slot on the plan. Nothing is erased. Its crawls, findings and history are kept, and add_project on the same domain brings the same project back with its history intact. Use it for a site you no longer work on, or one you registered by mistake. Returns projectId, domain and removed; calling it again is harmless. Destructive only in that tracking stops: open actions stay as they were, and no scheduled audit or check runs until add_project restores it. Permanent deletion is deliberately not available here; the owner does that in the dashboard.

ParametersJSON Schema
NameRequiredDescriptionDefault
projectIdYesProject id (a UUID) from add_project or list_projects, e.g. "0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30"

Output Schema

ParametersJSON Schema
NameRequiredDescription
domainYes
removedYestrue if the site was being tracked; false if it already was not
projectIdYes

TDQS

A4.6/5.0
Behavior5/5

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

Adds rich behavioral context beyond annotations: nothing is erased, history is retained, add_project restores the same project, open actions stay, no scheduled audits run until restored, and returns projectId/domain/removed. Annotations already mark it destructive and idempotent, but the description explains the exact nature of both.

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

Conciseness4/5

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

Front-loads the core effect and routes usage effectively, but is somewhat long and has minor overlap between 'Nothing is erased' and later reassurances about history and actions remaining. Most sentences still earn their place by answering distinct agent questions.

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

Completeness5/5

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

Given a complete input schema, an output schema, and annotations covering destructiveness and idempotency, the description fills the remaining gaps: reversibility, restoration path, permanent-deletion alternative, and exact response fields. Nothing an agent needs before calling is missing.

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

Parameters3/5

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

Schema description coverage is 100% and already documents the single projectId parameter with format and example. The description does not add parameter-specific meaning, so the baseline of 3 applies.

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

Purpose5/5

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

States a specific verb and resource ('Stop tracking a site') and immediately clarifies the effect: leaves list_projects, stops crawling/checking, frees a site slot. Distinguishes from siblings by naming list_projects and add_project, and by noting permanent deletion is not available here.

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

Usage Guidelines5/5

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

Explicitly says when to use it ('for a site you no longer work on, or one you registered by mistake') and when not to expect permanent deletion ('deliberately not available here; the owner does that in the dashboard'). It also guides on idempotency ('calling it again is harmless') and restoration via add_project.

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

run_auditRun a site auditAInspect

Queues a fresh crawl and audit of the site and returns the crawl id and status, up to maxPages pages (default 100; the response says how many it used). Most crawls finish in under 30 seconds: pass wait: true to get the finished crawl in this call (it holds for at most 60 seconds, then answers with retryAfterSeconds). Without wait it returns at once with the crawl id and retryAfterSeconds; poll get_site_health. Each call starts a new crawl that fetches the live site. Costs pages_crawled quota, checked up front: a month that cannot cover maxPages answers quota_exceeded at once. When it finishes, the action list is rebuilt automatically; read list_actions or get_next_work. Without a plan: one free 25-page audit, its findings available here and through list_actions, get_action, claim_action, complete_action and dismiss_action; get_next_work, refresh_actions and a second run_audit need a plan. The free audit is clamped to 25 pages and runs once; its findings are filed as actions for list_actions, and a second run_audit answers subscription_required.

ParametersJSON Schema
NameRequiredDescriptionDefault
waitNotrue holds the call until the crawl finishes, for at most 60 seconds; default false returns at once
maxPagesNoPages to crawl at most, 1-5000; default 100, e.g. 250 for a larger site
projectIdYesProject id (a UUID) from add_project or list_projects, e.g. "0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30"

Output Schema

ParametersJSON Schema
NameRequiredDescription
noteNoPresent only on the free preview: what the crawl produces and where to read it
errorNoWhy the crawl failed, when it did
statusYes
crawlIdYesPoll get_site_health for the result
maxPagesNoPresent only on the free preview: pages this crawl will cover, after clamping
maxPagesUsedYesThe page cap this crawl runs with
pagesCrawledNoPresent when the call waited
retryAfterSecondsNoPresent while the crawl is still running: wait this long, then get_site_health

TDQS

A4.7/5.0
Behavior5/5

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

Annotations only declare openWorldHint and non-idempotency; the description adds substantial context beyond them: quota consumption (pages_crawled, checked up front with quota_exceeded), the 60-second wait cap with retryAfterSeconds, the one-time free 25-page clamp, and that each call fetches the live site. This is exactly the behavioral disclosure annotations cannot carry.

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

Conciseness3/5

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

It is front-loaded and information-dense, but noticeably redundant: the free-audit/25-page/plan requirement is stated twice across the last two sentences, and the action-list rebuild is mentioned in two separate places. Some of that text could be consolidated without losing meaning.

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

Completeness5/5

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

For a mutation-style job-launch tool, the description covers quota, timing, polling, free-tier limits, upgrade gating, and downstream tools to read results. With an output schema present it need not detail return shape, and nothing an agent needs to invoke it correctly appears to be missing.

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

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3, but the description genuinely adds meaning: maxPages interacts with quota (a month that cannot cover maxPages fails up front) and is clamped to 25 on the free tier, and wait's 60-second ceiling with retryAfterSeconds is spelled out. It adds more than the schema fields alone convey.

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

Purpose5/5

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

The opening clause names a specific verb and resource ('Queues a fresh crawl and audit of the site') and states the immediate return ('the crawl id and status'). It is cleanly distinguishable from siblings like get_site_health (polling) and list_actions (consuming results), which the description explicitly names.

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

Usage Guidelines5/5

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

It gives explicit routing: pass wait:true to get the finished crawl, otherwise poll get_site_health; read list_actions or get_next_work after completion. It also states prerequisites, i.e. a second run_audit without a plan answers subscription_required, which is exactly the when/when-not guidance an agent needs.

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

set_project_profileDescribe what this site sellsA
Idempotent
Inspect

Step one of the growth recipe, and the gate on the rest of it. Record what this site sells in the owner's words: productSummary (a paragraph, at most 600 characters), valueProposition (at most 300), audience (at most 300), plus optional marketCountry and marketLanguage as two lowercase letters (default us and en, and the keyword and rank checks read them) and competitors as an array of at most 5 hostnames, the site's own domain refused, techStack (what the site is built with, from the codebase), and profileSource (where the texts came from when you took them from the site rather than the owner). Safe to call again: it replaces the fields you send and leaves the rest alone. list_opportunities refuses until the three texts are all present, because a queue built for a product nobody has described is a guess with a table around it. Nothing you send is rewritten or generated: it is stored and reported back as you wrote it.

ParametersJSON Schema
NameRequiredDescriptionDefault
audienceNoWho buys it, in the owner's words
projectIdYesProject id (a UUID) from add_project or list_projects, e.g. "0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30"
techStackNoWhat the site is built with; read it from the codebase (package.json, config files). The audit uses it to tell a framework's by-design behaviour from a problem, from the next run_audit on. null clears it and falls back to detectedStack.
competitorsNoHostnames, e.g. ["rival.com"]. Replaces the stored list; an empty array clears it.
marketCountryNoTwo lowercase letters, e.g. "us". Defaults to us.
profileSourceNoWhere the three texts came from if the owner did not write them, e.g. "the site's meta description and homepage hero". Empty string clears it.
marketLanguageNoTwo lowercase letters, e.g. "en". Defaults to en.
productSummaryNoWhat the product is, one paragraph. Send an empty string to clear it.
valuePropositionNoWhy someone picks it over the alternatives

Output Schema

ParametersJSON Schema
NameRequiredDescription
missingYesProfile fields still empty; the strategy tools refuse while this is non-empty
audienceYesWho buys it
completedYestrue once productSummary, valueProposition and audience are all filled in
projectIdYes
techStackYesWhat the site is built with, as declared; the audit prefers it over detectedStack
competitorsYesTracked competitor hostnames, at most 5
completedAtYes
detectedStackYesWhat the latest crawl recognised from the HTML, or null when nothing matched
marketCountryYesTwo-letter country the checks are run for, e.g. us
profileSourceYesWhere the texts came from, when the owner did not write them
marketLanguageYesTwo-letter language, e.g. en
productSummaryYesWhat the product is, as the customer wrote it
valuePropositionYesWhy someone picks it

TDQS

A4.6/5.0
Behavior5/5

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

Adds meaningful behavior beyond the annotations: 'Safe to call again: it replaces the fields you send and leaves the rest alone' documents partial-merge semantics that idempotentHint alone does not convey, and 'Nothing you send is rewritten or generated: it is stored and reported back as you wrote it' sets expectations about storage fidelity. It also discloses field-level constraints (own domain refused for competitors, defaults of us/en) that no annotation covers.

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

Conciseness4/5

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

Front-loads the essential role ('step one... gate on the rest of it') before field detail, and each clause carries operational content. It is on the long side and includes rhetorical flourishes ('a guess with a table around it') that are characterful but not strictly necessary.

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

Completeness5/5

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

For a 9-parameter mutation tool with an output schema (so returns need not be explained), the description covers the gating condition, defaults, clearing semantics, field constraints, and the write/merge behavior. Nothing an agent needs to call it correctly appears to be missing.

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

Parameters4/5

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

Schema coverage is already 100%, but the description still adds real meaning: it says marketCountry/marketLanguage 'default us and en, and the keyword and rank checks read them', that competitors caps at 5 hostnames and refuses the site's own domain, that techStack should be read from the codebase, and what profileSource is for. It goes beyond restating the schema rather than merely duplicating it.

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

Purpose5/5

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

States a specific verb and resource โ€” 'Record what this site sells in the owner's words' โ€” and enumerates the exact fields being set (productSummary, valueProposition, audience, marketCountry/Language, competitors, techStack, profileSource). It is clearly distinguishable from the read-side sibling get_project_profile and from add_project/list_projects.

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

Usage Guidelines4/5

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

Gives strong contextual guidance: it is 'step one of the growth recipe, and the gate on the rest of it', and it names the concrete dependency that 'list_opportunities refuses until the three texts are all present'. It does not name a sibling alternative for reading back the profile, so this falls just short of the explicit when/when-not/alternative bar.

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

Tool Schema Changelog

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

  1. 6 tool updates
    • Changedclaim_action2 fields changed
      • addedOutput schema / properties / alsoClosed
        Added value: +{
        +  "description": "Further findings closed by this call's actionIds, beyond the one reported here",
        +  "maximum": 9007199254740991,
        +  "minimum": -9007199254740991,
        +  "type": "integer"
        +}
      • addedOutput schema / properties / notFound
        Added value: +{
        +  "description": "actionIds that named no open finding of this project: already closed, or not ours",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
    • Changedcomplete_action3 fields changed
      • addedInput schema / properties / actionIds
        Added value: +{
        +  "description": "Further findings the same change closed. Only include what this commit actually fixed; ids that are not open findings of this project come back in notFound.",
        +  "items": {
        +    "type": "string"
        +  },
        +  "maxItems": 500,
        +  "type": "array"
        +}
      • addedOutput schema / properties / alsoClosed
        Added value: +{
        +  "description": "Further findings closed by this call's actionIds, beyond the one reported here",
        +  "maximum": 9007199254740991,
        +  "minimum": -9007199254740991,
        +  "type": "integer"
        +}
      • addedOutput schema / properties / notFound
        Added value: +{
        +  "description": "actionIds that named no open finding of this project: already closed, or not ours",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
    • Changeddismiss_action2 fields changed
      • addedOutput schema / properties / alsoClosed
        Added value: +{
        +  "description": "Further findings closed by this call's actionIds, beyond the one reported here",
        +  "maximum": 9007199254740991,
        +  "minimum": -9007199254740991,
        +  "type": "integer"
        +}
      • addedOutput schema / properties / notFound
        Added value: +{
        +  "description": "actionIds that named no open finding of this project: already closed, or not ours",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
    • Changedgeo_summary1 field changed
      • addedInput schema / properties / view
        Added value: +{
        +  "description": "brief (the default) is the rates and the top competitor domains. full adds the competitor URLs and fan-out queries per engine, which is far larger.",
        +  "enum": [
        +    "brief",
        +    "full"
        +  ],
        +  "type": "string"
        +}
    • Changedget_action2 fields changed
      • addedOutput schema / properties / alsoClosed
        Added value: +{
        +  "description": "Further findings closed by this call's actionIds, beyond the one reported here",
        +  "maximum": 9007199254740991,
        +  "minimum": -9007199254740991,
        +  "type": "integer"
        +}
      • addedOutput schema / properties / notFound
        Added value: +{
        +  "description": "actionIds that named no open finding of this project: already closed, or not ours",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
    • Changedget_next_work4 fields changed
      • changedOutput schema / properties / items / description
        Previous value: -"What to work on now, most important first. Empty when there is nothing to do."New value: +"What to work on now, most important first, one entry per kind of finding rather than one per finding. Empty when there is nothing to do."
      • addedOutput schema / properties / items / items / properties / sameFix
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "The other open findings that are the same piece of work. One entry can stand for many pages.",
        +  "properties": {
        +    "actionIds": {
        +      "description": "Pass to complete_action as actionIds to close the whole set with one note and one commit.",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "count": {
        +      "description": "Open findings of this kind, this one included: the blast radius",
        +      "maximum": 9007199254740991,
        +      "minimum": -9007199254740991,
        +      "type": "integer"
        +    },
        +    "fixScope": {
        +      "description": "How findings of this rule usually go: page is writing that belongs to one page, template is markup a shared layout emits, site is about the origin. It describes the rule, not your repository โ€” you are the one who knows.",
        +      "enum": [
        +        "page",
        +        "template",
        +        "site"
        +      ],
        +      "type": "string"
        +    },
        +    "key": {
        +      "description": "The audit rule, or the action type when there is none",
        +      "type": "string"
        +    },
        +    "morePages": {
        +      "description": "Pages beyond those listed",
        +      "maximum": 9007199254740991,
        +      "minimum": -9007199254740991,
        +      "type": "integer"
        +    },
        +    "pages": {
        +      "description": "Their pages, this one first",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "ruleId": {
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "samePages": {
        +      "description": "Other kinds of finding standing on exactly the same pages. They are separate edits, so they are separate entries, but they are one visit to each page rather than three.",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "key",
        +    "ruleId",
        +    "fixScope",
        +    "count",
        +    "pages",
        +    "morePages",
        +    "actionIds",
        +    "samePages"
        +  ],
        +  "type": "object"
        +}
      • changedOutput schema / properties / items / items / required
        Previous value: -[
        -  "importance",
        -  "action"
        -]New value: +[
        +  "importance",
        +  "action",
        +  "sameFix"
        +]
      • changedOutput schema / properties / remaining / description
        Previous value: -"Open findings behind these; call again when done with them"New value: +"Open findings not covered by these entries; call again when done with them"
  2. 27 tool updates
    • Changedadd_geo_prompts1 field changed
      • changedInput schema / properties / projectId / description
        Previous value: -"Project id (a UUID) from list_projects or add_project"New value: +"Project id (a UUID) from add_project or list_projects, e.g. \"0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30\""
    • Changedadd_keywords2 fields changed
      • changedInput schema / properties / projectId / description
        Previous value: -"Project id (a UUID) from list_projects or add_project"New value: +"Project id (a UUID) from add_project or list_projects, e.g. \"0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30\""
      • changedInput schema / properties / terms / description
        Previous value: -"The search phrases to track, as plain strings: [\"seo tool\", \"rank tracker\"]"New value: +"The search phrases to track, as plain strings, 1-200 per call: [\"seo tool\", \"rank tracker\"]"
    • Changedcheck_geo6 fields changed
      • addedInput schema / properties / force
        Added value: +{
        +  "description": "Re-check even though the last check is under 20 hours old. Bills again; leave unset unless a same-day re-check is genuinely needed",
        +  "type": "boolean"
        +}
      • changedInput schema / properties / projectId / description
        Previous value: -"Project id (a UUID) from list_projects or add_project"New value: +"Project id (a UUID) from add_project or list_projects, e.g. \"0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30\""
      • addedOutput schema / properties / lastCheckedAt
        Added value: +{
        +  "description": "ISO time of the project's newest check of this kind, null when never checked",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / nextCheckAfter
        Added value: +{
        +  "description": "Present only with fresh: when an unforced check will run again",
        +  "type": "string"
        +}
      • changedOutput schema / properties / status / description
        Previous value: -"queued when this call created the job. already_queued when the same job for this project was enqueued moments ago and this call was deduplicated: the work is coming and nothing extra was billed. nothing_to_check when the project tracks nothing for this run: no job was enqueued, nothing was billed, and hint names the tool to call first."New value: +"queued when this call created the job. already_queued when the same job for this project was enqueued moments ago and this call was deduplicated: the work is coming and nothing extra was billed. nothing_to_check when the project tracks nothing for this run: no job was enqueued, nothing was billed, and hint names the tool to call first. fresh when the last check is under 20 hours old: nothing was enqueued or billed, read the existing result now, and pass force: true only if a re-check today is genuinely needed."
      • changedOutput schema / properties / status / enum
        Previous value: -[
        -  "queued",
        -  "already_queued",
        -  "nothing_to_check"
        -]New value: +[
        +  "queued",
        +  "already_queued",
        +  "nothing_to_check",
        +  "fresh"
        +]
    • Changedcheck_rankings6 fields changed
      • addedInput schema / properties / force
        Added value: +{
        +  "description": "Re-check even though the last check is under 20 hours old. Bills again; leave unset unless a same-day re-check is genuinely needed",
        +  "type": "boolean"
        +}
      • changedInput schema / properties / projectId / description
        Previous value: -"Project id (a UUID) from list_projects or add_project"New value: +"Project id (a UUID) from add_project or list_projects, e.g. \"0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30\""
      • addedOutput schema / properties / lastCheckedAt
        Added value: +{
        +  "description": "ISO time of the project's newest check of this kind, null when never checked",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / nextCheckAfter
        Added value: +{
        +  "description": "Present only with fresh: when an unforced check will run again",
        +  "type": "string"
        +}
      • changedOutput schema / properties / status / description
        Previous value: -"queued when this call created the job. already_queued when the same job for this project was enqueued moments ago and this call was deduplicated: the work is coming and nothing extra was billed. nothing_to_check when the project tracks nothing for this run: no job was enqueued, nothing was billed, and hint names the tool to call first."New value: +"queued when this call created the job. already_queued when the same job for this project was enqueued moments ago and this call was deduplicated: the work is coming and nothing extra was billed. nothing_to_check when the project tracks nothing for this run: no job was enqueued, nothing was billed, and hint names the tool to call first. fresh when the last check is under 20 hours old: nothing was enqueued or billed, read the existing result now, and pass force: true only if a re-check today is genuinely needed."
      • changedOutput schema / properties / status / enum
        Previous value: -[
        -  "queued",
        -  "already_queued",
        -  "nothing_to_check"
        -]New value: +[
        +  "queued",
        +  "already_queued",
        +  "nothing_to_check",
        +  "fresh"
        +]
    • Changedclaim_action5 fields changed
      • changedInput schema / properties / actionId / description
        Previous value: -"Action id (a UUID) from the id field of list_actions"New value: +"Action id (a UUID) from the id field of a list_actions row, an exampleActionIds entry of a group, or get_next_work"
      • changedInput schema / properties / projectId / description
        Previous value: -"Project id (a UUID) from list_projects or add_project"New value: +"Project id (a UUID) from add_project or list_projects, e.g. \"0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30\""
      • removedOutput schema / properties / agentRunId
        Removed value: -{
        -  "description": "The brain run that filed this action, if any",
        -  "type": [
        -    "string",
        -    "null"
        -  ]
        -}
      • addedOutput schema / properties / refreshId
        Added value: +{
        +  "description": "The action-list refresh that filed this action, if any",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "id",
        -  "projectId",
        -  "agentRunId",
        -  "type",
        -  "priority",
        -  "title",
        -  "rationale",
        -  "targetUrl",
        -  "payload",
        -  "status",
        -  "claimedByApiKeyId",
        -  "claimedAt",
        -  "doneAt",
        -  "note",
        -  "commitSha",
        -  "createdAt",
        -  "updatedAt"
        -]New value: +[
        +  "id",
        +  "projectId",
        +  "refreshId",
        +  "type",
        +  "priority",
        +  "title",
        +  "rationale",
        +  "targetUrl",
        +  "payload",
        +  "status",
        +  "claimedByApiKeyId",
        +  "claimedAt",
        +  "doneAt",
        +  "note",
        +  "commitSha",
        +  "createdAt",
        +  "updatedAt"
        +]
    • Changedcomplete_action5 fields changed
      • changedInput schema / properties / actionId / description
        Previous value: -"Action id (a UUID) from the id field of list_actions"New value: +"Action id (a UUID) from the id field of a list_actions row, an exampleActionIds entry of a group, or get_next_work"
      • changedInput schema / properties / projectId / description
        Previous value: -"Project id (a UUID) from list_projects or add_project"New value: +"Project id (a UUID) from add_project or list_projects, e.g. \"0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30\""
      • removedOutput schema / properties / agentRunId
        Removed value: -{
        -  "description": "The brain run that filed this action, if any",
        -  "type": [
        -    "string",
        -    "null"
        -  ]
        -}
      • addedOutput schema / properties / refreshId
        Added value: +{
        +  "description": "The action-list refresh that filed this action, if any",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "id",
        -  "projectId",
        -  "agentRunId",
        -  "type",
        -  "priority",
        -  "title",
        -  "rationale",
        -  "targetUrl",
        -  "payload",
        -  "status",
        -  "claimedByApiKeyId",
        -  "claimedAt",
        -  "doneAt",
        -  "note",
        -  "commitSha",
        -  "createdAt",
        -  "updatedAt"
        -]New value: +[
        +  "id",
        +  "projectId",
        +  "refreshId",
        +  "type",
        +  "priority",
        +  "title",
        +  "rationale",
        +  "targetUrl",
        +  "payload",
        +  "status",
        +  "claimedByApiKeyId",
        +  "claimedAt",
        +  "doneAt",
        +  "note",
        +  "commitSha",
        +  "createdAt",
        +  "updatedAt"
        +]
    • Changeddismiss_action5 fields changed
      • changedInput schema / properties / actionId / description
        Previous value: -"Action id (a UUID) from the id field of list_actions"New value: +"Action id (a UUID) from the id field of a list_actions row, an exampleActionIds entry of a group, or get_next_work"
      • changedInput schema / properties / projectId / description
        Previous value: -"Project id (a UUID) from list_projects or add_project"New value: +"Project id (a UUID) from add_project or list_projects, e.g. \"0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30\""
      • removedOutput schema / properties / agentRunId
        Removed value: -{
        -  "description": "The brain run that filed this action, if any",
        -  "type": [
        -    "string",
        -    "null"
        -  ]
        -}
      • addedOutput schema / properties / refreshId
        Added value: +{
        +  "description": "The action-list refresh that filed this action, if any",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "id",
        -  "projectId",
        -  "agentRunId",
        -  "type",
        -  "priority",
        -  "title",
        -  "rationale",
        -  "targetUrl",
        -  "payload",
        -  "status",
        -  "claimedByApiKeyId",
        -  "claimedAt",
        -  "doneAt",
        -  "note",
        -  "commitSha",
        -  "createdAt",
        -  "updatedAt"
        -]New value: +[
        +  "id",
        +  "projectId",
        +  "refreshId",
        +  "type",
        +  "priority",
        +  "title",
        +  "rationale",
        +  "targetUrl",
        +  "payload",
        +  "status",
        +  "claimedByApiKeyId",
        +  "claimedAt",
        +  "doneAt",
        +  "note",
        +  "commitSha",
        +  "createdAt",
        +  "updatedAt"
        +]
    • Changedgeo_summary2 fields changed
      • addedInput schema / properties / days / description
        Added value: +"Window in days, counted back from now, 1-365; default 30, e.g. 90 for a quarter"
      • changedInput schema / properties / projectId / description
        Previous value: -"Project id (a UUID) from list_projects or add_project"New value: +"Project id (a UUID) from add_project or list_projects, e.g. \"0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30\""
    • Changedget_action5 fields changed
      • changedInput schema / properties / actionId / description
        Previous value: -"Action id (a UUID) from the id field of list_actions"New value: +"Action id (a UUID) from the id field of a list_actions row, an exampleActionIds entry of a group, or get_next_work"
      • changedInput schema / properties / projectId / description
        Previous value: -"Project id (a UUID) from list_projects or add_project"New value: +"Project id (a UUID) from add_project or list_projects, e.g. \"0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30\""
      • removedOutput schema / properties / agentRunId
        Removed value: -{
        -  "description": "The brain run that filed this action, if any",
        -  "type": [
        -    "string",
        -    "null"
        -  ]
        -}
      • addedOutput schema / properties / refreshId
        Added value: +{
        +  "description": "The action-list refresh that filed this action, if any",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "id",
        -  "projectId",
        -  "agentRunId",
        -  "type",
        -  "priority",
        -  "title",
        -  "rationale",
        -  "targetUrl",
        -  "payload",
        -  "status",
        -  "claimedByApiKeyId",
        -  "claimedAt",
        -  "doneAt",
        -  "note",
        -  "commitSha",
        -  "createdAt",
        -  "updatedAt"
        -]New value: +[
        +  "id",
        +  "projectId",
        +  "refreshId",
        +  "type",
        +  "priority",
        +  "title",
        +  "rationale",
        +  "targetUrl",
        +  "payload",
        +  "status",
        +  "claimedByApiKeyId",
        +  "claimedAt",
        +  "doneAt",
        +  "note",
        +  "commitSha",
        +  "createdAt",
        +  "updatedAt"
        +]
    • Changedget_behavior_digest2 fields changed
      • addedInput schema / properties / days / description
        Added value: +"Window in days, counted back from now, 1-90; default 7, e.g. 30 for a month"
      • changedInput schema / properties / projectId / description
        Previous value: -"Project id (a UUID) from list_projects or add_project"New value: +"Project id (a UUID) from add_project or list_projects, e.g. \"0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30\""
    • Changedget_content_brief1 field changed
      • changedInput schema / properties / projectId / description
        Previous value: -"Project id (a UUID) from list_projects or add_project"New value: +"Project id (a UUID) from add_project or list_projects, e.g. \"0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30\""
    • Changedget_next_work4 fields changed
      • changedInput schema / properties / projectId / description
        Previous value: -"Project id (a UUID) from list_projects or add_project"New value: +"Project id (a UUID) from add_project or list_projects, e.g. \"0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30\""
      • removedOutput schema / properties / items / items / properties / action / properties / agentRunId
        Removed value: -{
        -  "description": "The brain run that filed this action, if any",
        -  "type": [
        -    "string",
        -    "null"
        -  ]
        -}
      • addedOutput schema / properties / items / items / properties / action / properties / refreshId
        Added value: +{
        +  "description": "The action-list refresh that filed this action, if any",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • changedOutput schema / properties / items / items / properties / action / required
        Previous value: -[
        -  "id",
        -  "projectId",
        -  "agentRunId",
        -  "type",
        -  "priority",
        -  "title",
        -  "rationale",
        -  "targetUrl",
        -  "payload",
        -  "status",
        -  "claimedByApiKeyId",
        -  "claimedAt",
        -  "doneAt",
        -  "note",
        -  "commitSha",
        -  "createdAt",
        -  "updatedAt"
        -]New value: +[
        +  "id",
        +  "projectId",
        +  "refreshId",
        +  "type",
        +  "priority",
        +  "title",
        +  "rationale",
        +  "targetUrl",
        +  "payload",
        +  "status",
        +  "claimedByApiKeyId",
        +  "claimedAt",
        +  "doneAt",
        +  "note",
        +  "commitSha",
        +  "createdAt",
        +  "updatedAt"
        +]
    • Changedget_page_history1 field changed
      • changedInput schema / properties / projectId / description
        Previous value: -"Project id (a UUID) from list_projects or add_project"New value: +"Project id (a UUID) from add_project or list_projects, e.g. \"0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30\""
    • Changedget_page_profile3 fields changed
      • addedInput schema / properties / days / description
        Added value: +"Window in days, counted back from now, 1-90; default 7"
      • addedInput schema / properties / path / description
        Added value: +"Page path exactly as recorded, e.g. \"/pricing\": no scheme, host or query string (query strings are dropped when visits are recorded). \"/pricing\" and \"/pricing/\" are different pages, so copy the path from get_behavior_digest"
      • changedInput schema / properties / projectId / description
        Previous value: -"Project id (a UUID) from list_projects or add_project"New value: +"Project id (a UUID) from add_project or list_projects, e.g. \"0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30\""
    • Changedget_project_profile1 field changed
      • changedInput schema / properties / projectId / description
        Previous value: -"Project id (a UUID) from list_projects or add_project"New value: +"Project id (a UUID) from add_project or list_projects, e.g. \"0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30\""
    • Changedget_setup_status1 field changed
      • changedInput schema / properties / projectId / description
        Previous value: -"Project id (a UUID) from list_projects or add_project"New value: +"Project id (a UUID) from add_project or list_projects, e.g. \"0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30\""
    • Changedget_site_health1 field changed
      • changedInput schema / properties / projectId / description
        Previous value: -"Project id (a UUID) from list_projects or add_project"New value: +"Project id (a UUID) from add_project or list_projects, e.g. \"0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30\""
    • Changedlist_actions4 fields changed
      • changedInput schema / properties / projectId / description
        Previous value: -"Project id (a UUID) from list_projects or add_project"New value: +"Project id (a UUID) from add_project or list_projects, e.g. \"0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30\""
      • addedInput schema / properties / status / description
        Added value: +"Which actions to return; default open. open: not yet taken; claimed: taken by an agent with claim_action; done: closed with complete_action; dismissed: closed with dismiss_action and a reason"
      • removedOutput schema / properties / actions / items / properties / agentRunId
        Removed value: -{
        -  "description": "The brain run that filed this action, if any",
        -  "type": [
        -    "string",
        -    "null"
        -  ]
        -}
      • addedOutput schema / properties / actions / items / properties / refreshId
        Added value: +{
        +  "description": "The action-list refresh that filed this action, if any",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
    • Changedlist_keywords1 field changed
      • changedInput schema / properties / projectId / description
        Previous value: -"Project id (a UUID) from list_projects or add_project"New value: +"Project id (a UUID) from add_project or list_projects, e.g. \"0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30\""
    • Changedlist_opportunities1 field changed
      • changedInput schema / properties / projectId / description
        Previous value: -"Project id (a UUID) from list_projects or add_project"New value: +"Project id (a UUID) from add_project or list_projects, e.g. \"0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30\""
    • Changedlist_regressions1 field changed
      • changedInput schema / properties / projectId / description
        Previous value: -"Project id (a UUID) from list_projects or add_project"New value: +"Project id (a UUID) from add_project or list_projects, e.g. \"0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30\""
    • Changedrank_history2 fields changed
      • changedInput schema / properties / projectId / description
        Previous value: -"Project id (a UUID) from list_projects or add_project"New value: +"Project id (a UUID) from add_project or list_projects, e.g. \"0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30\""
      • changedOutput schema / properties / samples / items / properties / position / description
        Previous value: -"null means not found in the tracked result set"New value: +"null means not found in the top 30 results, the depth every check reads"
    • Addedrefresh_actions
    • Changedremove_project1 field changed
      • changedInput schema / properties / projectId / description
        Previous value: -"Project id (a UUID) from list_projects or add_project"New value: +"Project id (a UUID) from add_project or list_projects, e.g. \"0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30\""
    • Changedrun_audit3 fields changed
      • changedInput schema / properties / maxPages / description
        Previous value: -"Pages to crawl at most; default 100"New value: +"Pages to crawl at most, 1-5000; default 100, e.g. 250 for a larger site"
      • changedInput schema / properties / projectId / description
        Previous value: -"Project id (a UUID) from list_projects or add_project"New value: +"Project id (a UUID) from add_project or list_projects, e.g. \"0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30\""
      • changedInput schema / properties / wait / description
        Previous value: -"Hold the call until the crawl finishes, for at most 60 seconds"New value: +"true holds the call until the crawl finishes, for at most 60 seconds; default false returns at once"
    • Removedrun_brain
    • Changedset_project_profile1 field changed
      • changedInput schema / properties / projectId / description
        Previous value: -"Project id (a UUID) from list_projects or add_project"New value: +"Project id (a UUID) from add_project or list_projects, e.g. \"0190f7a2-8c1e-7d3a-9b4f-2e6c1a5d8f30\""
  3. 8 tool updates
    • Changedclaim_action2 fields changed
      • addedOutput schema / properties / commitSha
        Added value: +{
        +  "description": "The commit the agent reported when completing this, if it reported one",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "id",
        -  "projectId",
        -  "agentRunId",
        -  "type",
        -  "priority",
        -  "title",
        -  "rationale",
        -  "targetUrl",
        -  "payload",
        -  "status",
        -  "claimedByApiKeyId",
        -  "claimedAt",
        -  "doneAt",
        -  "note",
        -  "createdAt",
        -  "updatedAt"
        -]New value: +[
        +  "id",
        +  "projectId",
        +  "agentRunId",
        +  "type",
        +  "priority",
        +  "title",
        +  "rationale",
        +  "targetUrl",
        +  "payload",
        +  "status",
        +  "claimedByApiKeyId",
        +  "claimedAt",
        +  "doneAt",
        +  "note",
        +  "commitSha",
        +  "createdAt",
        +  "updatedAt"
        +]
    • Changedcomplete_action3 fields changed
      • addedInput schema / properties / commit
        Added value: +{
        +  "description": "The commit that carries the change, so the fix can be traced and reverted.",
        +  "pattern": "^[0-9a-f]{7,64}$",
        +  "type": "string"
        +}
      • addedOutput schema / properties / commitSha
        Added value: +{
        +  "description": "The commit the agent reported when completing this, if it reported one",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "id",
        -  "projectId",
        -  "agentRunId",
        -  "type",
        -  "priority",
        -  "title",
        -  "rationale",
        -  "targetUrl",
        -  "payload",
        -  "status",
        -  "claimedByApiKeyId",
        -  "claimedAt",
        -  "doneAt",
        -  "note",
        -  "createdAt",
        -  "updatedAt"
        -]New value: +[
        +  "id",
        +  "projectId",
        +  "agentRunId",
        +  "type",
        +  "priority",
        +  "title",
        +  "rationale",
        +  "targetUrl",
        +  "payload",
        +  "status",
        +  "claimedByApiKeyId",
        +  "claimedAt",
        +  "doneAt",
        +  "note",
        +  "commitSha",
        +  "createdAt",
        +  "updatedAt"
        +]
    • Changeddismiss_action2 fields changed
      • addedOutput schema / properties / commitSha
        Added value: +{
        +  "description": "The commit the agent reported when completing this, if it reported one",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "id",
        -  "projectId",
        -  "agentRunId",
        -  "type",
        -  "priority",
        -  "title",
        -  "rationale",
        -  "targetUrl",
        -  "payload",
        -  "status",
        -  "claimedByApiKeyId",
        -  "claimedAt",
        -  "doneAt",
        -  "note",
        -  "createdAt",
        -  "updatedAt"
        -]New value: +[
        +  "id",
        +  "projectId",
        +  "agentRunId",
        +  "type",
        +  "priority",
        +  "title",
        +  "rationale",
        +  "targetUrl",
        +  "payload",
        +  "status",
        +  "claimedByApiKeyId",
        +  "claimedAt",
        +  "doneAt",
        +  "note",
        +  "commitSha",
        +  "createdAt",
        +  "updatedAt"
        +]
    • Changedget_action2 fields changed
      • addedOutput schema / properties / commitSha
        Added value: +{
        +  "description": "The commit the agent reported when completing this, if it reported one",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "id",
        -  "projectId",
        -  "agentRunId",
        -  "type",
        -  "priority",
        -  "title",
        -  "rationale",
        -  "targetUrl",
        -  "payload",
        -  "status",
        -  "claimedByApiKeyId",
        -  "claimedAt",
        -  "doneAt",
        -  "note",
        -  "createdAt",
        -  "updatedAt"
        -]New value: +[
        +  "id",
        +  "projectId",
        +  "agentRunId",
        +  "type",
        +  "priority",
        +  "title",
        +  "rationale",
        +  "targetUrl",
        +  "payload",
        +  "status",
        +  "claimedByApiKeyId",
        +  "claimedAt",
        +  "doneAt",
        +  "note",
        +  "commitSha",
        +  "createdAt",
        +  "updatedAt"
        +]
    • Addedget_content_brief
    • Addedget_next_work
    • Addedget_page_history
    • Addedlist_regressions
  4. 1 tool update
    • Changedlist_actions8 fields changed
      • addedOutput schema / properties / actions / items / properties / lastSeenAt
        Added value: +{
        +  "description": "When a run last measured this problem; its rationale and payload are from that run as an ISO 8601 timestamp",
        +  "type": "string"
        +}
      • changedOutput schema / properties / actions / items / required
        Previous value: -[
        -  "id",
        -  "type",
        -  "ruleId",
        -  "priority",
        -  "title",
        -  "rationale",
        -  "targetUrl",
        -  "payload",
        -  "status",
        -  "note"
        -]New value: +[
        +  "id",
        +  "type",
        +  "ruleId",
        +  "priority",
        +  "title",
        +  "rationale",
        +  "targetUrl",
        +  "payload",
        +  "status",
        +  "note",
        +  "lastSeenAt"
        +]
      • addedOutput schema / properties / groups / items / properties / examples / items / properties / evidence
        Added value: +{
        +  "additionalProperties": {
        +    "type": [
        +      "number",
        +      "boolean"
        +    ]
        +  },
        +  "description": "This example's own measurements",
        +  "propertyNames": {
        +    "type": "string"
        +  },
        +  "type": "object"
        +}
      • changedOutput schema / properties / groups / items / properties / examples / items / required
        Previous value: -[
        -  "id",
        -  "targetUrl"
        -]New value: +[
        +  "id",
        +  "targetUrl",
        +  "evidence"
        +]
      • addedOutput schema / properties / groups / items / properties / measured
        Added value: +{
        +  "additionalProperties": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "max": {
        +        "type": "number"
        +      },
        +      "min": {
        +        "type": "number"
        +      }
        +    },
        +    "required": [
        +      "min",
        +      "max"
        +    ],
        +    "type": "object"
        +  },
        +  "description": "Each numeric measurement across the group, as the range it spans",
        +  "propertyNames": {
        +    "type": "string"
        +  },
        +  "type": "object"
        +}
      • changedOutput schema / properties / groups / items / required
        Previous value: -[
        -  "key",
        -  "type",
        -  "ruleId",
        -  "priority",
        -  "count",
        -  "rationale",
        -  "examples",
        -  "moreNotShown"
        -]New value: +[
        +  "key",
        +  "type",
        +  "ruleId",
        +  "priority",
        +  "count",
        +  "rationale",
        +  "measured",
        +  "examples",
        +  "moreNotShown"
        +]
      • addedOutput schema / properties / priorityScale
        Added value: +{
        +  "type": "string"
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "view",
        -  "status",
        -  "total"
        -]New value: +[
        +  "view",
        +  "priorityScale",
        +  "status",
        +  "total"
        +]
  5. 9 tool updates
    • Changedclaim_action3 fields changed
      • removedOutput schema / properties / organizationId
        Removed value: -{
        -  "type": "string"
        -}
      • changedOutput schema / properties / type / enum
        Previous value: -[
        -  "fix_title",
        -  "fix_meta_description",
        -  "fix_heading",
        -  "fix_broken_links",
        -  "add_canonical",
        -  "add_structured_data",
        -  "improve_content",
        -  "create_content",
        -  "geo_gap",
        -  "allow_ai_crawler",
        -  "ssr_content",
        -  "refresh_content",
        -  "add_evidence",
        -  "restructure_sections",
        -  "cover_fanout_query",
        -  "third_party_placement",
        -  "claim_review_profile",
        -  "fix_intent_mismatch",
        -  "improve_landing_page",
        -  "fix_friction",
        -  "other"
        -]New value: +[
        +  "fix_title",
        +  "fix_meta_description",
        +  "fix_heading",
        +  "fix_broken_links",
        +  "add_canonical",
        +  "add_structured_data",
        +  "improve_content",
        +  "create_content",
        +  "geo_gap",
        +  "allow_ai_crawler",
        +  "ssr_content",
        +  "refresh_content",
        +  "add_evidence",
        +  "restructure_sections",
        +  "cover_fanout_query",
        +  "third_party_placement",
        +  "claim_review_profile",
        +  "fix_intent_mismatch",
        +  "improve_landing_page",
        +  "fix_friction",
        +  "review_indexing",
        +  "improve_speed",
        +  "add_internal_links",
        +  "add_sitemap",
        +  "review_crawler_access",
        +  "other"
        +]
      • changedOutput schema / required
        Previous value: -[
        -  "id",
        -  "organizationId",
        -  "projectId",
        -  "agentRunId",
        -  "type",
        -  "priority",
        -  "title",
        -  "rationale",
        -  "targetUrl",
        -  "payload",
        -  "status",
        -  "claimedByApiKeyId",
        -  "claimedAt",
        -  "doneAt",
        -  "note",
        -  "createdAt",
        -  "updatedAt"
        -]New value: +[
        +  "id",
        +  "projectId",
        +  "agentRunId",
        +  "type",
        +  "priority",
        +  "title",
        +  "rationale",
        +  "targetUrl",
        +  "payload",
        +  "status",
        +  "claimedByApiKeyId",
        +  "claimedAt",
        +  "doneAt",
        +  "note",
        +  "createdAt",
        +  "updatedAt"
        +]
    • Changedcomplete_action3 fields changed
      • removedOutput schema / properties / organizationId
        Removed value: -{
        -  "type": "string"
        -}
      • changedOutput schema / properties / type / enum
        Previous value: -[
        -  "fix_title",
        -  "fix_meta_description",
        -  "fix_heading",
        -  "fix_broken_links",
        -  "add_canonical",
        -  "add_structured_data",
        -  "improve_content",
        -  "create_content",
        -  "geo_gap",
        -  "allow_ai_crawler",
        -  "ssr_content",
        -  "refresh_content",
        -  "add_evidence",
        -  "restructure_sections",
        -  "cover_fanout_query",
        -  "third_party_placement",
        -  "claim_review_profile",
        -  "fix_intent_mismatch",
        -  "improve_landing_page",
        -  "fix_friction",
        -  "other"
        -]New value: +[
        +  "fix_title",
        +  "fix_meta_description",
        +  "fix_heading",
        +  "fix_broken_links",
        +  "add_canonical",
        +  "add_structured_data",
        +  "improve_content",
        +  "create_content",
        +  "geo_gap",
        +  "allow_ai_crawler",
        +  "ssr_content",
        +  "refresh_content",
        +  "add_evidence",
        +  "restructure_sections",
        +  "cover_fanout_query",
        +  "third_party_placement",
        +  "claim_review_profile",
        +  "fix_intent_mismatch",
        +  "improve_landing_page",
        +  "fix_friction",
        +  "review_indexing",
        +  "improve_speed",
        +  "add_internal_links",
        +  "add_sitemap",
        +  "review_crawler_access",
        +  "other"
        +]
      • changedOutput schema / required
        Previous value: -[
        -  "id",
        -  "organizationId",
        -  "projectId",
        -  "agentRunId",
        -  "type",
        -  "priority",
        -  "title",
        -  "rationale",
        -  "targetUrl",
        -  "payload",
        -  "status",
        -  "claimedByApiKeyId",
        -  "claimedAt",
        -  "doneAt",
        -  "note",
        -  "createdAt",
        -  "updatedAt"
        -]New value: +[
        +  "id",
        +  "projectId",
        +  "agentRunId",
        +  "type",
        +  "priority",
        +  "title",
        +  "rationale",
        +  "targetUrl",
        +  "payload",
        +  "status",
        +  "claimedByApiKeyId",
        +  "claimedAt",
        +  "doneAt",
        +  "note",
        +  "createdAt",
        +  "updatedAt"
        +]
    • Changeddismiss_action3 fields changed
      • removedOutput schema / properties / organizationId
        Removed value: -{
        -  "type": "string"
        -}
      • changedOutput schema / properties / type / enum
        Previous value: -[
        -  "fix_title",
        -  "fix_meta_description",
        -  "fix_heading",
        -  "fix_broken_links",
        -  "add_canonical",
        -  "add_structured_data",
        -  "improve_content",
        -  "create_content",
        -  "geo_gap",
        -  "allow_ai_crawler",
        -  "ssr_content",
        -  "refresh_content",
        -  "add_evidence",
        -  "restructure_sections",
        -  "cover_fanout_query",
        -  "third_party_placement",
        -  "claim_review_profile",
        -  "fix_intent_mismatch",
        -  "improve_landing_page",
        -  "fix_friction",
        -  "other"
        -]New value: +[
        +  "fix_title",
        +  "fix_meta_description",
        +  "fix_heading",
        +  "fix_broken_links",
        +  "add_canonical",
        +  "add_structured_data",
        +  "improve_content",
        +  "create_content",
        +  "geo_gap",
        +  "allow_ai_crawler",
        +  "ssr_content",
        +  "refresh_content",
        +  "add_evidence",
        +  "restructure_sections",
        +  "cover_fanout_query",
        +  "third_party_placement",
        +  "claim_review_profile",
        +  "fix_intent_mismatch",
        +  "improve_landing_page",
        +  "fix_friction",
        +  "review_indexing",
        +  "improve_speed",
        +  "add_internal_links",
        +  "add_sitemap",
        +  "review_crawler_access",
        +  "other"
        +]
      • changedOutput schema / required
        Previous value: -[
        -  "id",
        -  "organizationId",
        -  "projectId",
        -  "agentRunId",
        -  "type",
        -  "priority",
        -  "title",
        -  "rationale",
        -  "targetUrl",
        -  "payload",
        -  "status",
        -  "claimedByApiKeyId",
        -  "claimedAt",
        -  "doneAt",
        -  "note",
        -  "createdAt",
        -  "updatedAt"
        -]New value: +[
        +  "id",
        +  "projectId",
        +  "agentRunId",
        +  "type",
        +  "priority",
        +  "title",
        +  "rationale",
        +  "targetUrl",
        +  "payload",
        +  "status",
        +  "claimedByApiKeyId",
        +  "claimedAt",
        +  "doneAt",
        +  "note",
        +  "createdAt",
        +  "updatedAt"
        +]
    • Changedget_action3 fields changed
      • removedOutput schema / properties / organizationId
        Removed value: -{
        -  "type": "string"
        -}
      • changedOutput schema / properties / type / enum
        Previous value: -[
        -  "fix_title",
        -  "fix_meta_description",
        -  "fix_heading",
        -  "fix_broken_links",
        -  "add_canonical",
        -  "add_structured_data",
        -  "improve_content",
        -  "create_content",
        -  "geo_gap",
        -  "allow_ai_crawler",
        -  "ssr_content",
        -  "refresh_content",
        -  "add_evidence",
        -  "restructure_sections",
        -  "cover_fanout_query",
        -  "third_party_placement",
        -  "claim_review_profile",
        -  "fix_intent_mismatch",
        -  "improve_landing_page",
        -  "fix_friction",
        -  "other"
        -]New value: +[
        +  "fix_title",
        +  "fix_meta_description",
        +  "fix_heading",
        +  "fix_broken_links",
        +  "add_canonical",
        +  "add_structured_data",
        +  "improve_content",
        +  "create_content",
        +  "geo_gap",
        +  "allow_ai_crawler",
        +  "ssr_content",
        +  "refresh_content",
        +  "add_evidence",
        +  "restructure_sections",
        +  "cover_fanout_query",
        +  "third_party_placement",
        +  "claim_review_profile",
        +  "fix_intent_mismatch",
        +  "improve_landing_page",
        +  "fix_friction",
        +  "review_indexing",
        +  "improve_speed",
        +  "add_internal_links",
        +  "add_sitemap",
        +  "review_crawler_access",
        +  "other"
        +]
      • changedOutput schema / required
        Previous value: -[
        -  "id",
        -  "organizationId",
        -  "projectId",
        -  "agentRunId",
        -  "type",
        -  "priority",
        -  "title",
        -  "rationale",
        -  "targetUrl",
        -  "payload",
        -  "status",
        -  "claimedByApiKeyId",
        -  "claimedAt",
        -  "doneAt",
        -  "note",
        -  "createdAt",
        -  "updatedAt"
        -]New value: +[
        +  "id",
        +  "projectId",
        +  "agentRunId",
        +  "type",
        +  "priority",
        +  "title",
        +  "rationale",
        +  "targetUrl",
        +  "payload",
        +  "status",
        +  "claimedByApiKeyId",
        +  "claimedAt",
        +  "doneAt",
        +  "note",
        +  "createdAt",
        +  "updatedAt"
        +]
    • Changedget_project_profile4 fields changed
      • addedOutput schema / properties / detectedStack
        Added value: +{
        +  "description": "What the latest crawl recognised from the HTML, or null when nothing matched",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / profileSource
        Added value: +{
        +  "description": "Where the texts came from, when the owner did not write them",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / techStack
        Added value: +{
        +  "description": "What the site is built with, as declared; the audit prefers it over detectedStack",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "projectId",
        -  "productSummary",
        -  "valueProposition",
        -  "audience",
        -  "marketCountry",
        -  "marketLanguage",
        -  "competitors",
        -  "completed",
        -  "completedAt",
        -  "missing"
        -]New value: +[
        +  "projectId",
        +  "productSummary",
        +  "valueProposition",
        +  "audience",
        +  "marketCountry",
        +  "marketLanguage",
        +  "competitors",
        +  "techStack",
        +  "detectedStack",
        +  "profileSource",
        +  "completed",
        +  "completedAt",
        +  "missing"
        +]
    • Addedget_setup_status
    • Changedlist_actions18 fields changed
      • addedInput schema / properties / limit
        Added value: +{
        +  "description": "Rows per page, default 50",
        +  "maximum": 200,
        +  "minimum": 1,
        +  "type": "integer"
        +}
      • addedInput schema / properties / offset
        Added value: +{
        +  "description": "Rows to skip, from nextOffset",
        +  "maximum": 9007199254740991,
        +  "minimum": 0,
        +  "type": "integer"
        +}
      • addedInput schema / properties / ruleId
        Added value: +{
        +  "description": "Only actions filed from this audit rule, e.g. missing_title (a group's key)",
        +  "maxLength": 64,
        +  "type": "string"
        +}
      • addedInput schema / properties / type
        Added value: +{
        +  "description": "Only actions of this category",
        +  "enum": [
        +    "fix_title",
        +    "fix_meta_description",
        +    "fix_heading",
        +    "fix_broken_links",
        +    "add_canonical",
        +    "add_structured_data",
        +    "improve_content",
        +    "create_content",
        +    "geo_gap",
        +    "allow_ai_crawler",
        +    "ssr_content",
        +    "refresh_content",
        +    "add_evidence",
        +    "restructure_sections",
        +    "cover_fanout_query",
        +    "third_party_placement",
        +    "claim_review_profile",
        +    "fix_intent_mismatch",
        +    "improve_landing_page",
        +    "fix_friction",
        +    "review_indexing",
        +    "improve_speed",
        +    "add_internal_links",
        +    "add_sitemap",
        +    "review_crawler_access",
        +    "other"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / verbose
        Added value: +{
        +  "description": "Include bookkeeping fields on each row; default false",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / view
        Added value: +{
        +  "description": "grouped (default) or rows; rows is the default when ruleId or type is given",
        +  "enum": [
        +    "grouped",
        +    "rows"
        +  ],
        +  "type": "string"
        +}
      • addedOutput schema / properties / actions / description
        Added value: +"The rows view, one page"
      • removedOutput schema / properties / actions / items / properties / organizationId
        Removed value: -{
        -  "type": "string"
        -}
      • addedOutput schema / properties / actions / items / properties / ruleId
        Added value: +{
        +  "description": "The audit rule that filed it, when one did",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • changedOutput schema / properties / actions / items / properties / type / enum
        Previous value: -[
        -  "fix_title",
        -  "fix_meta_description",
        -  "fix_heading",
        -  "fix_broken_links",
        -  "add_canonical",
        -  "add_structured_data",
        -  "improve_content",
        -  "create_content",
        -  "geo_gap",
        -  "allow_ai_crawler",
        -  "ssr_content",
        -  "refresh_content",
        -  "add_evidence",
        -  "restructure_sections",
        -  "cover_fanout_query",
        -  "third_party_placement",
        -  "claim_review_profile",
        -  "fix_intent_mismatch",
        -  "improve_landing_page",
        -  "fix_friction",
        -  "other"
        -]New value: +[
        +  "fix_title",
        +  "fix_meta_description",
        +  "fix_heading",
        +  "fix_broken_links",
        +  "add_canonical",
        +  "add_structured_data",
        +  "improve_content",
        +  "create_content",
        +  "geo_gap",
        +  "allow_ai_crawler",
        +  "ssr_content",
        +  "refresh_content",
        +  "add_evidence",
        +  "restructure_sections",
        +  "cover_fanout_query",
        +  "third_party_placement",
        +  "claim_review_profile",
        +  "fix_intent_mismatch",
        +  "improve_landing_page",
        +  "fix_friction",
        +  "review_indexing",
        +  "improve_speed",
        +  "add_internal_links",
        +  "add_sitemap",
        +  "review_crawler_access",
        +  "other"
        +]
      • changedOutput schema / properties / actions / items / required
        Previous value: -[
        -  "id",
        -  "organizationId",
        -  "projectId",
        -  "agentRunId",
        -  "type",
        -  "priority",
        -  "title",
        -  "rationale",
        -  "targetUrl",
        -  "payload",
        -  "status",
        -  "claimedByApiKeyId",
        -  "claimedAt",
        -  "doneAt",
        -  "note",
        -  "createdAt",
        -  "updatedAt"
        -]New value: +[
        +  "id",
        +  "type",
        +  "ruleId",
        +  "priority",
        +  "title",
        +  "rationale",
        +  "targetUrl",
        +  "payload",
        +  "status",
        +  "note"
        +]
      • addedOutput schema / properties / groups
        Added value: +{
        +  "description": "The grouped view",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "count": {
        +        "maximum": 9007199254740991,
        +        "minimum": -9007199254740991,
        +        "type": "integer"
        +      },
        +      "examples": {
        +        "items": {
        +          "additionalProperties": false,
        +          "properties": {
        +            "id": {
        +              "type": "string"
        +            },
        +            "targetUrl": {
        +              "type": [
        +                "string",
        +                "null"
        +              ]
        +            }
        +          },
        +          "required": [
        +            "id",
        +            "targetUrl"
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "key": {
        +        "description": "Pass as ruleId (or, when ruleId is null, as type) for the rows",
        +        "type": "string"
        +      },
        +      "moreNotShown": {
        +        "description": "Items in the group beyond the examples",
        +        "maximum": 9007199254740991,
        +        "minimum": -9007199254740991,
        +        "type": "integer"
        +      },
        +      "priority": {
        +        "description": "The group's most urgent priority; 1 is most urgent",
        +        "maximum": 9007199254740991,
        +        "minimum": -9007199254740991,
        +        "type": "integer"
        +      },
        +      "rationale": {
        +        "description": "The first item's rationale; the others differ in their numbers",
        +        "type": "string"
        +      },
        +      "ruleId": {
        +        "type": [
        +          "string",
        +          "null"
        +        ]
        +      },
        +      "type": {
        +        "description": "Category of problem",
        +        "enum": [
        +          "fix_title",
        +          "fix_meta_description",
        +          "fix_heading",
        +          "fix_broken_links",
        +          "add_canonical",
        +          "add_structured_data",
        +          "improve_content",
        +          "create_content",
        +          "geo_gap",
        +          "allow_ai_crawler",
        +          "ssr_content",
        +          "refresh_content",
        +          "add_evidence",
        +          "restructure_sections",
        +          "cover_fanout_query",
        +          "third_party_placement",
        +          "claim_review_profile",
        +          "fix_intent_mismatch",
        +          "improve_landing_page",
        +          "fix_friction",
        +          "review_indexing",
        +          "improve_speed",
        +          "add_internal_links",
        +          "add_sitemap",
        +          "review_crawler_access",
        +          "other"
        +        ],
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "key",
        +      "type",
        +      "ruleId",
        +      "priority",
        +      "count",
        +      "rationale",
        +      "examples",
        +      "moreNotShown"
        +    ],
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / nextOffset
        Added value: +{
        +  "anyOf": [
        +    {
        +      "maximum": 9007199254740991,
        +      "minimum": -9007199254740991,
        +      "type": "integer"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "Pass as offset for the next page; null on the last one"
        +}
      • addedOutput schema / properties / offset
        Added value: +{
        +  "maximum": 9007199254740991,
        +  "minimum": -9007199254740991,
        +  "type": "integer"
        +}
      • addedOutput schema / properties / status
        Added value: +{
        +  "enum": [
        +    "open",
        +    "claimed",
        +    "done",
        +    "dismissed"
        +  ],
        +  "type": "string"
        +}
      • addedOutput schema / properties / total
        Added value: +{
        +  "description": "Actions matching the status and filters",
        +  "maximum": 9007199254740991,
        +  "minimum": -9007199254740991,
        +  "type": "integer"
        +}
      • addedOutput schema / properties / view
        Added value: +{
        +  "enum": [
        +    "grouped",
        +    "rows"
        +  ],
        +  "type": "string"
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "actions"
        -]New value: +[
        +  "view",
        +  "status",
        +  "total"
        +]
    • Changedrun_audit7 fields changed
      • addedInput schema / properties / maxPages / description
        Added value: +"Pages to crawl at most; default 100"
      • addedInput schema / properties / wait
        Added value: +{
        +  "description": "Hold the call until the crawl finishes, for at most 60 seconds",
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / error
        Added value: +{
        +  "description": "Why the crawl failed, when it did",
        +  "type": "string"
        +}
      • addedOutput schema / properties / maxPagesUsed
        Added value: +{
        +  "description": "The page cap this crawl runs with",
        +  "maximum": 9007199254740991,
        +  "minimum": -9007199254740991,
        +  "type": "integer"
        +}
      • addedOutput schema / properties / pagesCrawled
        Added value: +{
        +  "description": "Present when the call waited",
        +  "maximum": 9007199254740991,
        +  "minimum": -9007199254740991,
        +  "type": "integer"
        +}
      • addedOutput schema / properties / retryAfterSeconds
        Added value: +{
        +  "description": "Present while the crawl is still running: wait this long, then get_site_health",
        +  "maximum": 9007199254740991,
        +  "minimum": -9007199254740991,
        +  "type": "integer"
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "crawlId",
        -  "status"
        -]New value: +[
        +  "crawlId",
        +  "status",
        +  "maxPagesUsed"
        +]
    • Changedset_project_profile6 fields changed
      • addedInput schema / properties / profileSource
        Added value: +{
        +  "description": "Where the three texts came from if the owner did not write them, e.g. \"the site's meta description and homepage hero\". Empty string clears it.",
        +  "maxLength": 200,
        +  "type": "string"
        +}
      • addedInput schema / properties / techStack
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "nextjs",
        +        "nuxt",
        +        "sveltekit",
        +        "remix",
        +        "astro",
        +        "gatsby",
        +        "react_spa",
        +        "vue_spa",
        +        "angular",
        +        "wordpress",
        +        "shopify",
        +        "webflow",
        +        "wix",
        +        "squarespace",
        +        "framer",
        +        "static",
        +        "other"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "What the site is built with; read it from the codebase (package.json, config files). The audit uses it to tell a framework's by-design behaviour from a problem, from the next run_audit on. null clears it and falls back to detectedStack."
        +}
      • addedOutput schema / properties / detectedStack
        Added value: +{
        +  "description": "What the latest crawl recognised from the HTML, or null when nothing matched",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / profileSource
        Added value: +{
        +  "description": "Where the texts came from, when the owner did not write them",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / techStack
        Added value: +{
        +  "description": "What the site is built with, as declared; the audit prefers it over detectedStack",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "projectId",
        -  "productSummary",
        -  "valueProposition",
        -  "audience",
        -  "marketCountry",
        -  "marketLanguage",
        -  "competitors",
        -  "completed",
        -  "completedAt",
        -  "missing"
        -]New value: +[
        +  "projectId",
        +  "productSummary",
        +  "valueProposition",
        +  "audience",
        +  "marketCountry",
        +  "marketLanguage",
        +  "competitors",
        +  "techStack",
        +  "detectedStack",
        +  "profileSource",
        +  "completed",
        +  "completedAt",
        +  "missing"
        +]
  6. 23 tool updates
    • Addedadd_geo_prompts
    • Addedadd_keywords
    • Addedadd_project
    • Addedcheck_geo
    • Addedcheck_rankings
    • Addedclaim_action
    • Addedcomplete_action
    • Addeddismiss_action
    • Addedgeo_summary
    • Addedget_action
    • Addedget_behavior_digest
    • Addedget_page_profile
    • Addedget_project_profile
    • Addedget_site_health
    • Addedlist_actions
    • Addedlist_keywords
    • Addedlist_opportunities
    • Addedlist_projects
    • Addedrank_history
    • Addedremove_project
    • Addedrun_audit
    • Addedrun_brain
    • Addedset_project_profile
  7. 1 tool update
    • First observedhow_to_authenticate

Related MCP Connectors

Related MCP Servers

  • -
    license
    Not graded
    quality
    C
    maintenance
    Enables AI assistants to perform comprehensive SEO and GEO measurements, including site audits, keyword research, ranking tracking, and brand visibility analysis across search engines and generative AI platforms.
    -
  • A
    license
    A
    quality
    A
    maintenance
    Provides AI-visibility scoring and site auditing capabilities for websites, enabling agents to check how sites appear in AI engines like ChatGPT and Perplexity, run full SEO/security audits, and monitor changes over time.
    15
    350 npm
    1
    MIT
  • F
    license
    A
    quality
    B
    maintenance
    Enables AI assistants to search Google SERPs, track rankings across locations, run Lighthouse SEO audits, find broken internal links, analyze backlinks, and get keyword volume data through a hosted service.
    13
    -
  • A
    license
    A
    quality
    D
    maintenance
    Enables AI assistants to access SurfRank's AI visibility analytics platform through 24 tools. It allows agents to run AI-visibility reports, research keywords, track competitors, and manage projects directly from chat interfaces.
    24
    10 npm
    MIT
Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.