GetCited
REMOTE · APP.GETCITED.DEV · SCANNED SEP 29
SEO and AI-visibility operator tools: site health, ranked actions, ranks, visitor behavior.
Available components
How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. How we score → Why this is hard to score →
Endpoint Security80
- The endpoint's TLS certificate is valid, in date, and uses a strong key. View diagnostics → Pass
- No authorisation is required to call this server. Every tool declares its destructiveHint and none is destructive, so open access doesn't expose one. See how to fix → View diagnostics → Partial
- HTTPS is enforced; there's no plaintext access path. View diagnostics → Pass
- The HSTS (Strict-Transport-Security) header is present. View diagnostics → Pass
- DNSSEC check failed: this domain isn't protected by DNSSEC. See how to fix → View diagnostics → Fail
Transport & Reachability100
- Verified streamable-http transport via a live MCP handshake. View diagnostics → Pass
Schema Quality & AI Usability18
- AI-judged instruction clarity (poor).Fail
- Context-footprint check failed: tool/resource definitions use about 4818 tokens (~166/item across 29 items; 29 tools + 0 resources), over budget; trim descriptions and params. See how to fix → Fail
- Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management30
- Stability observed for 9 of 30 days with no destabilising changes; credit accrues until the full window elapses.Partial
Tool Coverage98
- 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
- 93% of tool parameters carry a description.Partial
- Structured output schemas are declared (83% of tools); any adoption earns full credit.Pass
Tool Safety75
- No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
- All 1 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation.Pass
- Manipulation check failed: an AI judge found 1 of 30 captured unit(s) of tool text manipulative, the first being "server instructions". See how to fix → Fail
Capabilities100
- Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.Pass
How do I install the GetCited MCP server?
GetCited is a hosted endpoint at https://app.getcited.dev/api/mcp, so there is nothing to install locally. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.
remote · app.getcited.dev
claude mcp add --transport http dev-getcited-mcp 'https://app.getcited.dev/api/mcp'
{
"mcpServers": {
"dev-getcited-mcp": {
"url": "https://app.getcited.dev/api/mcp"
}
}
} {
"servers": {
"dev-getcited-mcp": {
"type": "http",
"url": "https://app.getcited.dev/api/mcp"
}
}
} [mcp_servers.dev-getcited-mcp] url = "https://app.getcited.dev/api/mcp"
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"dev-getcited-mcp": {
"type": "remote",
"url": "https://app.getcited.dev/api/mcp",
"enabled": true
}
}
} openclaw mcp add dev-getcited-mcp --url 'https://app.getcited.dev/api/mcp' --transport streamable-http
mcp_servers:
dev-getcited-mcp:
url: "https://app.getcited.dev/api/mcp" {
"McpServers": {
"dev-getcited-mcp": {
"Transport": "http",
"Url": "https://app.getcited.dev/api/mcp"
}
}
} assistant mcp add dev-getcited-mcp -t streamable-http -u 'https://app.getcited.dev/api/mcp'
{
"mcpServers": {
"dev-getcited-mcp": {
"type": "http",
"url": "https://app.getcited.dev/api/mcp"
}
}
} The mcpServers block is a cross-client convention. Remote transports vary, so check your client's docs.
Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.
- 29 Sept 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 27 to 30. That category is still filling its 30-day observation window: 8 days of observed history at the previous scan, 9 at this one. The score rises as the window fills, whether or not the server changes.
- 28 Sept 26 0
- We updated how we score, so this day's move reflects our rubric, not a change to the server See what changed → functional
- 27 Sept 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 20 to 23. That category is still filling its 30-day observation window: 6 days of observed history at the previous scan, 7 at this one. The score rises as the window fills, whether or not the server changes.
- 25 Sept 26 0
- We updated how we score, so this day's move reflects our rubric, not a change to the server See what changed → functional
- 24 Sept 26 −10
- Judged manipulation: pass → fail ▼ security
- The server rewrote its instructions, which are the text every model session reads security
- Tool “how_to_authenticate” rewrote its description, which is the text the model reads security
- Schema quality: 273 → 150 ▲ functional
- First check of Tool coverage: 80 functional
- First check of Tool coverage: 91 functional
- Schema quality: excellent → poor functional
- Destructive annotations: pass → 100 functional
- Server version: 0.1.0 → 0.3.0 functional
- New tool “add_geo_prompts” functional
- New tool “add_keywords” functional
- New tool “add_project” functional
- New tool “check_geo” functional
- New tool “check_rankings” functional
- New tool “claim_action” functional
- New tool “complete_action” functional
- New tool “dismiss_action” functional
- New tool “geo_summary” functional
- New tool “get_action” functional
- New tool “get_behavior_digest” functional
- New tool “get_page_profile” functional
- New tool “get_project_profile” functional
- New tool “get_setup_status” functional
- New tool “get_site_health” functional
- New tool “list_actions” functional
- New tool “list_keywords” functional
- New tool “list_opportunities” functional
- New tool “list_projects” functional
- New tool “rank_history” functional
- New tool “remove_project” functional
- New tool “run_audit” functional
- New tool “run_brain” functional
- New tool “set_project_profile” functional
- 22 Sept 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 3 to 7. That category is still filling its 30-day observation window: 1 days of observed history at the previous scan, 2 at this one. The score rises as the window fills, whether or not the server changes.
- 21 Sept 26 0
- Stability: unverified → 0.03 ▲ functional
- 20 Sept 26 73
First indexed and scored.
Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.
Captured 29 Sept 2026 · Probed https://app.getcited.dev/api/mcp
TLS valid
Negotiated TLS 1.3 with TLS_AES_128_GCM_SHA256 .
| Subject | Issuer | Valid from | Valid until | Key | Signature | Serial |
|---|---|---|---|---|---|---|
| CN=getcited.dev | CN=YE1,O=Let's Encrypt,C=US | 16 Sept 2026 | 15 Dec 2026 | ECDSA 256 | ECDSA-SHA384 | 5e1d5674b64b4440403db44069a56a20e16 |
| SANs: *.getcited.dev, getcited.dev | ||||||
| CN=YE1,O=Let's Encrypt,C=US (CA) | CN=Root YE,O=ISRG,C=US | 3 Sept 2025 | 2 Sept 2028 | ECDSA 384 | ECDSA-SHA384 | 5ddd70dd31f801c85c186a7a04b80afe |
| CN=Root YE,O=ISRG,C=US (CA) | CN=ISRG Root X2,O=Internet Security Research Group,C=US | 13 May 2026 | 2 Sept 2032 | ECDSA 384 | ECDSA-SHA384 | 872165fc34b6e5fba8add5b3705fb53a |
| CN=ISRG Root X2,O=Internet Security Research Group,C=US (CA) | CN=ISRG Root X1,O=Internet Security Research Group,C=US | 13 May 2026 | 2 Sept 2032 | ECDSA 384 | SHA256-RSA | 6c8f1dc727c7117f7baf853ac980f9cd |
Background: What to check on a remote MCP endpoint →
DNSSEC insecure
Validation of app.getcited.dev. — Not signed
| Zone | DS | Keys | Algorithms | Outcome |
|---|---|---|---|---|
| . | trust_anchor | 20326, 38696 | 8, 8 | Verified |
| dev. | present | 60074 | 8 | Verified |
| getcited.dev. | absent | Unsigned (proven) parent-signed NSEC/NSEC3 proves an unsigned delegation |
Authentication No authorisation required
The endpoint answered without asking for a token. Anyone who knows the URL can reach it.
| Result | No authorisation required |
|---|---|
| HTTP status | 200 |
| Header | Value |
|---|---|
| strict-transport-security | max-age=63072000; includeSubDomains; preload |
| content-security-policy | frame-ancestors 'none' |
| x-content-type-options | nosniff |
| x-frame-options | DENY |
| referrer-policy | strict-origin-when-cross-origin |
| permissions-policy | camera=(), microphone=(), geolocation=(), browsing-topics=() |
Background: How OAuth 2.1 works in the 2026 MCP spec →
Transports 2 probes
| Transport | URL | Outcome | Status | Location |
|---|---|---|---|---|
| streamable-http | https://app.getcited.dev/api/mcp | Verified | 200 | |
| http (plaintext) | http://app.getcited.dev/api/mcp | HTTPS enforced | 301 | https://app.getcited.dev/api/mcp |
The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →
add_geo_prompts Add GEO prompts ~180
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. Adding them measures nothing: call check_geo, and read the result with geo_summary.
| Name | Type | Req | Description |
|---|---|---|---|
| projectId | string | yes | Project id (a UUID) from list_projects or add_project |
| prompts | array | yes | Array of objects, one per prompt: [{ prompt: "best seo tool for agents", stage: "bofu" }] |
| Name | Type | Req | Description |
|---|---|---|---|
| added | integer | yes | Rows inserted; duplicates are skipped |
No examples provided.
add_keywords Add keywords ~122
Pass `terms`, an array of plain search phrases (terms: ["seo tool", "rank tracker"]), with the projectId from add_project or list_projects. Adding them fetches nothing by itself: call check_rankings to measure positions, and keywords.enrich runs when the worker schedule is on. Search volume and difficulty arrive with the first enrichment.
| Name | Type | Req | Description |
|---|---|---|---|
| projectId | string | yes | Project id (a UUID) from list_projects or add_project |
| terms | array | yes | The search phrases to track, as plain strings: ["seo tool", "rank tracker"] |
| Name | Type | Req | Description |
|---|---|---|---|
| added | integer | yes | Rows inserted; duplicates are skipped |
No examples provided.
add_project Track a site ~147
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.
| Name | Type | Req | Description |
|---|---|---|---|
| brandName | string | – | How the brand is written, when it differs from the domain |
| domain | string | yes | Domain of the site you are working in, e.g. example.com |
| Name | Type | Req | Description |
|---|---|---|---|
| brandName | string|null | yes | – |
| created | boolean | yes | true if this call registered the site, false if it was already tracked |
| domain | string | yes | The normalized domain that is tracked |
| note | string | – | Present only on the free preview: what it includes and what it does not |
| plan | string | – | Present only when there is no subscription: this account is on the free preview |
| projectId | string | yes | Pass this to every other tool |
No examples provided.
check_geo Check AI answer engines now ~127
Queue a run of every tracked GEO prompt against each configured AI answer engine. 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.
| Name | Type | Req | Description |
|---|---|---|---|
| projectId | string | yes | Project id (a UUID) from list_projects or add_project |
| Name | Type | Req | Description |
|---|---|---|---|
| hint | string | – | Present only with nothing_to_check: the tool to call before checking again |
| jobId | string|null | yes | Job id, null when this call was deduplicated into an already-queued run |
| pollWith | string | yes | Call geo_summary once the worker has finished the run |
| prompts | integer | yes | Active GEO prompts the run will ask, once on every configured engine; 0 queues nothing |
| status | string | yes | 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. noth… |
No examples provided.
check_rankings Check keyword rankings now ~147
Queue a search-position check for every keyword tracked on this project. 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.
| Name | Type | Req | Description |
|---|---|---|---|
| projectId | string | yes | Project id (a UUID) from list_projects or add_project |
| Name | Type | Req | Description |
|---|---|---|---|
| hint | string | – | Present only with nothing_to_check: the tool to call before checking again |
| jobId | string|null | yes | Job id, null when this call was deduplicated into an already-queued run |
| keywords | integer | yes | Tracked keywords the run will check, one rank_check of quota each; 0 queues nothing |
| pollWith | string | yes | Call rank_history once the worker has finished the run |
| status | string | yes | 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. noth… |
No examples provided.
claim_action Claim an action ~63
Mark an open problem as claimed by this agent before working on it.
| Name | Type | Req | Description |
|---|---|---|---|
| actionId | string | yes | Action id (a UUID) from the id field of list_actions |
| projectId | string | yes | Project id (a UUID) from list_projects or add_project |
| Name | Type | Req | Description |
|---|---|---|---|
| agentRunId | string|null | yes | The brain run that filed this action, if any |
| claimedAt | – | yes | – |
| claimedByApiKeyId | string|null | yes | – |
| commitSha | string|null | yes | The commit the agent reported when completing this, if it reported one |
| createdAt | string | yes | When the action was filed as an ISO 8601 timestamp |
| doneAt | – | yes | – |
| id | string | yes | – |
| note | string|null | yes | Why the agent closed this: required on dismissal, optional on completion |
| payload | object | yes | Evidence; shape varies by type |
| priority | integer | yes | 1 is most urgent, 5 least |
| projectId | string | yes | – |
| rationale | string | yes | What was measured and why it matters |
| status | string | yes | – |
| targetUrl | string|null | yes | The affected URL, if the problem is page-level |
| title | string | yes | – |
| type | string | yes | Category of problem |
| updatedAt | string | yes | When the action last changed as an ISO 8601 timestamp |
No examples provided.
complete_action Complete an action ~175
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.
| Name | Type | Req | Description |
|---|---|---|---|
| actionId | string | yes | Action id (a UUID) from the id field of list_actions |
| commit | string | – | The commit that carries the change, so the fix can be traced and reverted. |
| note | string | – | What you changed, in one line. Shown to the owner alongside the finding. |
| projectId | string | yes | Project id (a UUID) from list_projects or add_project |
| Name | Type | Req | Description |
|---|---|---|---|
| agentRunId | string|null | yes | The brain run that filed this action, if any |
| claimedAt | – | yes | – |
| claimedByApiKeyId | string|null | yes | – |
| commitSha | string|null | yes | The commit the agent reported when completing this, if it reported one |
| createdAt | string | yes | When the action was filed as an ISO 8601 timestamp |
| doneAt | – | yes | – |
| id | string | yes | – |
| note | string|null | yes | Why the agent closed this: required on dismissal, optional on completion |
| payload | object | yes | Evidence; shape varies by type |
| priority | integer | yes | 1 is most urgent, 5 least |
| projectId | string | yes | – |
| rationale | string | yes | What was measured and why it matters |
| status | string | yes | – |
| targetUrl | string|null | yes | The affected URL, if the problem is page-level |
| title | string | yes | – |
| type | string | yes | Category of problem |
| updatedAt | string | yes | When the action last changed as an ISO 8601 timestamp |
No examples provided.
dismiss_action Dismiss an action ~148
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.
| Name | Type | Req | Description |
|---|---|---|---|
| actionId | string | yes | Action id (a UUID) from the id field of list_actions |
| projectId | string | yes | Project id (a UUID) from list_projects or add_project |
| reason | string | yes | Why this finding does not apply to this site, in your own words. Shown to the owner, so a bare 'not applicable' is not useful. |
| Name | Type | Req | Description |
|---|---|---|---|
| agentRunId | string|null | yes | The brain run that filed this action, if any |
| claimedAt | – | yes | – |
| claimedByApiKeyId | string|null | yes | – |
| commitSha | string|null | yes | The commit the agent reported when completing this, if it reported one |
| createdAt | string | yes | When the action was filed as an ISO 8601 timestamp |
| doneAt | – | yes | – |
| id | string | yes | – |
| note | string|null | yes | Why the agent closed this: required on dismissal, optional on completion |
| payload | object | yes | Evidence; shape varies by type |
| priority | integer | yes | 1 is most urgent, 5 least |
| projectId | string | yes | – |
| rationale | string | yes | What was measured and why it matters |
| status | string | yes | – |
| targetUrl | string|null | yes | The affected URL, if the problem is page-level |
| title | string | yes | – |
| type | string | yes | Category of problem |
| updatedAt | string | yes | When the action last changed as an ISO 8601 timestamp |
No examples provided.
geo_summary GEO visibility summary ~71
Appearance frequency per prompt and engine over the last N days (default 30): runs, cited and mentioned rates, competitor domains, fan-out queries. Never a per-run rank.
| Name | Type | Req | Description |
|---|---|---|---|
| days | integer | – | – |
| projectId | string | yes | Project id (a UUID) from list_projects or add_project |
No output schema declared.
No examples provided.
get_action Get an action ~65
One problem in full: its category, target URL, rationale and evidence payload.
| Name | Type | Req | Description |
|---|---|---|---|
| actionId | string | yes | Action id (a UUID) from the id field of list_actions |
| projectId | string | yes | Project id (a UUID) from list_projects or add_project |
| Name | Type | Req | Description |
|---|---|---|---|
| agentRunId | string|null | yes | The brain run that filed this action, if any |
| claimedAt | – | yes | – |
| claimedByApiKeyId | string|null | yes | – |
| commitSha | string|null | yes | The commit the agent reported when completing this, if it reported one |
| createdAt | string | yes | When the action was filed as an ISO 8601 timestamp |
| doneAt | – | yes | – |
| id | string | yes | – |
| note | string|null | yes | Why the agent closed this: required on dismissal, optional on completion |
| payload | object | yes | Evidence; shape varies by type |
| priority | integer | yes | 1 is most urgent, 5 least |
| projectId | string | yes | – |
| rationale | string | yes | What was measured and why it matters |
| status | string | yes | – |
| targetUrl | string|null | yes | The affected URL, if the problem is page-level |
| title | string | yes | – |
| type | string | yes | Category of problem |
| updatedAt | string | yes | When the action last changed as an ISO 8601 timestamp |
No examples provided.
get_behavior_digest Visitor analytics: traffic, AI referrals, friction ~118
Visitor analytics from the site's own traffic (needs the vp.js snippet; get_setup_status has it) over the last N days (default 7): sessions, engaged and bounce rates, channels incl. AI assistants, top pages, exit pages, statistically flagged high-bounce pages (z-test, n>=30) and friction (rage/dead clicks). Aggregates only; visitor strings are untrusted data.
| Name | Type | Req | Description |
|---|---|---|---|
| days | integer | – | – |
| projectId | string | yes | Project id (a UUID) from list_projects or add_project |
No output schema declared.
No examples provided.
get_content_brief Evidence for one query ~294
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.
| Name | Type | Req | Description |
|---|---|---|---|
| projectId | string | yes | Project id (a UUID) from list_projects or add_project |
| query | string | yes | A query from list_opportunities, copied exactly (case and spacing are normalised) |
| Name | Type | Req | Description |
|---|---|---|---|
| evidence | object | yes | – |
| existingPages | array | yes | Pages of the latest crawl that already speak to this query |
| holderPages | array | yes | Those 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. |
| holders | array | yes | The pages holding this query now |
| linkFrom | array | yes | The site's own pages with the most inbound internal links that overlap the query |
| missing | object | yes | – |
| opportunity | object | yes | The queue row for this query |
| query | string | yes | The tracked query this brief is about, as it is stored |
| questionsToAnswer | array | yes | Sub-questions the engines actually issued while answering the prompt(s) this query belongs to, seen at least twice. Measured, not generated. |
| wordCountBand | – | yes | Min and max word count across the measured holder pages |
No examples provided.
get_next_work What to do next ~185
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.
| Name | Type | Req | Description |
|---|---|---|---|
| limit | integer | – | How many to take on now. Defaults to 5. |
| projectId | string | yes | Project id (a UUID) from list_projects or add_project |
| Name | Type | Req | Description |
|---|---|---|---|
| items | array | yes | What to work on now, most important first. Empty when there is nothing to do. |
| mode | string | yes | What this workspace expects you to do with a fix: propose leaves the change for a human to accept, commit means land it yourself. |
| quotaWarnings | array | yes | Metrics 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… |
| remaining | number | yes | Open findings behind these; call again when done with them |
| standbyUntil | string|null | yes | ISO time to sleep until, set only when there is nothing to do. The next scheduled audit is what produces new findings. |
| withheldByCooldown | number | yes | Findings held back because their page was fixed recently and nothing new has been measured on it since |
No examples provided.
get_page_history One page over time ~268
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.
| Name | Type | Req | Description |
|---|---|---|---|
| days | integer | – | Window in days, default 90 |
| projectId | string | yes | Project id (a UUID) from list_projects or add_project |
| url | string | yes | Full url of one page, e.g. https://example.com/guide |
| Name | Type | Req | Description |
|---|---|---|---|
| days | integer | yes | Window the timeline covers |
| events | array | yes | One row per measurement, newest first |
| url | string | yes | The page the timeline is for, as it was asked for |
No examples provided.
get_page_profile Page behavior profile ~87
Behavior profile for one path over the last N days: pageviews, entries, bounce and scroll rates, active time, rage/dead clicks, and a z-test of its bounce rate against the rest of the site.
| Name | Type | Req | Description |
|---|---|---|---|
| days | integer | – | – |
| path | string | yes | – |
| projectId | string | yes | Project id (a UUID) from list_projects or add_project |
No output schema declared.
No examples provided.
get_project_profile Read the site's profile ~106
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.
| Name | Type | Req | Description |
|---|---|---|---|
| projectId | string | yes | Project id (a UUID) from list_projects or add_project |
| Name | Type | Req | Description |
|---|---|---|---|
| audience | string|null | yes | Who buys it |
| competitors | array | yes | Tracked competitor hostnames, at most 5 |
| completed | boolean | yes | true once productSummary, valueProposition and audience are all filled in |
| completedAt | – | yes | – |
| detectedStack | string|null | yes | What the latest crawl recognised from the HTML, or null when nothing matched |
| marketCountry | string | yes | Two-letter country the checks are run for, e.g. us |
| marketLanguage | string | yes | Two-letter language, e.g. en |
| missing | array | yes | Profile fields still empty; the strategy tools refuse while this is non-empty |
| productSummary | string|null | yes | What the product is, as the customer wrote it |
| profileSource | string|null | yes | Where the texts came from, when the owner did not write them |
| projectId | string | yes | – |
| techStack | string|null | yes | What the site is built with, as declared; the audit prefers it over detectedStack |
| valueProposition | string|null | yes | Why someone picks it |
No examples provided.
get_setup_status Onboarding checklist ~125
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.
| Name | Type | Req | Description |
|---|---|---|---|
| projectId | string | yes | Project id (a UUID) from list_projects or add_project |
| Name | Type | Req | Description |
|---|---|---|---|
| complete | boolean | yes | – |
| domain | string | yes | – |
| next | – | yes | The first step still open; call its tool |
| plan | string | yes | The workspace plan; "none" is the free preview, where only run_audit runs |
| projectId | string | yes | – |
| steps | array | yes | – |
No examples provided.
get_site_health Site health ~78
Latest crawl status, issue counts by severity and rule, open action count and scores. Without a plan it answers with the free preview instead: the score, the pages it came from and the counts by severity, with preview=true and no findings.
| Name | Type | Req | Description |
|---|---|---|---|
| projectId | string | yes | Project id (a UUID) from list_projects or add_project |
No output schema declared.
No examples provided.
how_to_authenticate GetCited is not authenticated ~43
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.
Input schema present but exposes no named parameters.
No output schema declared.
No examples provided.
list_actions List actions ~304
Prioritized problems for a project, most urgent first; priority 1 is most urgent, 5 least. 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). Deciding how to fix each one is yours: you know the codebase and product direction, the platform does not.
| Name | Type | Req | Description |
|---|---|---|---|
| limit | integer | – | Rows per page, default 50 |
| offset | integer | – | Rows to skip, from nextOffset |
| projectId | string | yes | Project id (a UUID) from list_projects or add_project |
| ruleId | string | – | Only actions filed from this audit rule, e.g. missing_title (a group's key) |
| status | string | – | – |
| type | string | – | Only actions of this category |
| verbose | boolean | – | Include bookkeeping fields on each row; default false |
| view | string | – | grouped (default) or rows; rows is the default when ruleId or type is given |
| Name | Type | Req | Description |
|---|---|---|---|
| actions | array | – | The rows view, one page |
| groups | array | – | The grouped view |
| nextOffset | – | – | Pass as offset for the next page; null on the last one |
| offset | integer | – | – |
| priorityScale | string | yes | – |
| status | string | yes | – |
| total | integer | yes | Actions matching the status and filters |
| view | string | yes | – |
No examples provided.
list_keywords List keywords ~43
Tracked keywords with latest volume, difficulty, position and AI Overview status.
| Name | Type | Req | Description |
|---|---|---|---|
| projectId | string | yes | Project id (a UUID) from list_projects or add_project |
| Name | Type | Req | Description |
|---|---|---|---|
| keywords | array | yes | – |
No examples provided.
list_opportunities Queries this site does not hold ~279
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.
| Name | Type | Req | Description |
|---|---|---|---|
| kind | string | – | Return only rows of this kind; omit for all three |
| limit | integer | – | Rows to return, default 50 |
| projectId | string | yes | Project id (a UUID) from list_projects or add_project |
| Name | Type | Req | Description |
|---|---|---|---|
| gapFormula | string | yes | The exact arithmetic behind gap, and the sort order |
| opportunities | array | yes | – |
| windowDays | integer | yes | Rolling window every count in a row is measured over |
No examples provided.
list_projects List projects ~18
List the sites this API key can operate on.
Input schema present but exposes no named parameters.
| Name | Type | Req | Description |
|---|---|---|---|
| projects | array | yes | – |
No examples provided.
list_regressions What went backwards ~241
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.
| Name | Type | Req | Description |
|---|---|---|---|
| days | integer | – | Window in days, default 30 |
| projectId | string | yes | Project id (a UUID) from list_projects or add_project |
| Name | Type | Req | Description |
|---|---|---|---|
| regressions | array | yes | Sorted by kind, then by the size of the drop |
| thresholds | object | yes | The exact floors a movement has to clear to be reported |
| windowDays | integer | yes | Window both halves of every comparison come from |
No examples provided.
rank_history Keyword rank history ~170
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.
| Name | Type | Req | Description |
|---|---|---|---|
| days | integer | – | How many days back to sample, default 30 |
| keywordId | string | yes | Keyword id (a UUID) from the id field of list_keywords |
| projectId | string | yes | Project id (a UUID) from list_projects or add_project |
| Name | Type | Req | Description |
|---|---|---|---|
| samples | array | yes | – |
| status | string | yes | no_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 samp… |
No examples provided.
remove_project Stop tracking a site ~119
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. Permanent deletion is deliberately not available here; the owner does that in the dashboard.
| Name | Type | Req | Description |
|---|---|---|---|
| projectId | string | yes | Project id (a UUID) from list_projects or add_project |
| Name | Type | Req | Description |
|---|---|---|---|
| domain | string | yes | – |
| projectId | string | yes | – |
| removed | boolean | yes | true if the site was being tracked; false if it already was not |
No examples provided.
run_audit Run a site audit ~183
Queue a fresh crawl and audit of the site, 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. Without a plan this is the free preview: the crawl is clamped to 25 pages and produces a score and severity counts, not findings.
| Name | Type | Req | Description |
|---|---|---|---|
| maxPages | integer | – | Pages to crawl at most; default 100 |
| projectId | string | yes | Project id (a UUID) from list_projects or add_project |
| wait | boolean | – | Hold the call until the crawl finishes, for at most 60 seconds |
| Name | Type | Req | Description |
|---|---|---|---|
| crawlId | string | yes | Poll get_site_health for the result |
| error | string | – | Why the crawl failed, when it did |
| maxPages | integer | – | Present only on the free preview: pages this crawl will cover, after clamping |
| maxPagesUsed | integer | yes | The page cap this crawl runs with |
| note | string | – | Present only on the free preview: what the crawl produces and where to read it |
| pagesCrawled | integer | – | Present when the call waited |
| retryAfterSeconds | integer | – | Present while the crawl is still running: wait this long, then get_site_health |
| status | string | yes | – |
No examples provided.
run_brain Analyse all measurements and file new findings ~173
Turns measurements into actions: queues an analysis pass over everything already measured for this project (crawl issues, ranks, GEO visibility, visitor behavior) and files what it finds as new actions. A crawl already runs it on its own; call it after check_rankings or check_geo results land, or when the queue looks stale. The work runs asynchronously in the worker and takes minutes; this returns as soon as it is queued. Poll list_actions for the result. It reasons over stored data only, so run check_rankings, check_geo or run_audit first if the data is stale. Costs one brain_run of quota. Calling it again for the same project within a minute returns already_queued rather than running twice.
| Name | Type | Req | Description |
|---|---|---|---|
| projectId | string | yes | Project id (a UUID) from list_projects or add_project |
| Name | Type | Req | Description |
|---|---|---|---|
| jobId | string|null | yes | Job id, null when this call was deduplicated into an already-queued run |
| pollWith | string | yes | Call list_actions once the worker has finished the run |
| status | string | yes | 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. |
| trigger | string | yes | How the run was triggered; always manual over MCP |
No examples provided.
set_project_profile Describe what this site sells ~453
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.
| Name | Type | Req | Description |
|---|---|---|---|
| audience | string | – | Who buys it, in the owner's words |
| competitors | array | – | Hostnames, e.g. ["rival.com"]. Replaces the stored list; an empty array clears it. |
| marketCountry | string | – | Two lowercase letters, e.g. "us". Defaults to us. |
| marketLanguage | string | – | Two lowercase letters, e.g. "en". Defaults to en. |
| productSummary | string | – | What the product is, one paragraph. Send an empty string to clear it. |
| profileSource | string | – | 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. |
| projectId | string | yes | Project id (a UUID) from list_projects or add_project |
| techStack | – | – | 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 clear… |
| valueProposition | string | – | Why someone picks it over the alternatives |
| Name | Type | Req | Description |
|---|---|---|---|
| audience | string|null | yes | Who buys it |
| competitors | array | yes | Tracked competitor hostnames, at most 5 |
| completed | boolean | yes | true once productSummary, valueProposition and audience are all filled in |
| completedAt | – | yes | – |
| detectedStack | string|null | yes | What the latest crawl recognised from the HTML, or null when nothing matched |
| marketCountry | string | yes | Two-letter country the checks are run for, e.g. us |
| marketLanguage | string | yes | Two-letter language, e.g. en |
| missing | array | yes | Profile fields still empty; the strategy tools refuse while this is non-empty |
| productSummary | string|null | yes | What the product is, as the customer wrote it |
| profileSource | string|null | yes | Where the texts came from, when the owner did not write them |
| projectId | string | yes | – |
| techStack | string|null | yes | What the site is built with, as declared; the audit prefers it over detectedStack |
| valueProposition | string|null | yes | Why someone picks it |
No examples provided.
What is the GetCited MCP server?
GetCited is an MCP server listed in the public MCP registry as dev.getcited/mcp. SEO and AI-visibility operator tools: site health, ranked actions, ranks, visitor behavior. This page covers its hosted endpoint (https://app.getcited.dev/api/mcp).
Is the GetCited MCP server safe to use?
GetCited scores 66 out of 100 on VerifyMCP. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.
What tools does the GetCited MCP server expose?
GetCited exposes 29 tools: how_to_authenticate, get_setup_status, list_projects, add_project, remove_project, and 24 more. Their descriptions and schemas cost roughly 4,532 tokens of context every time the server is loaded.
Does the GetCited MCP server require authentication?
No. We connected to GetCited without credentials and it answered, so anything it exposes is reachable by anyone who knows the address.
Is the GetCited MCP server still maintained?
GetCited is still listed as active in the MCP registry. We last reached this channel on 29 September 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.