What the agent does
Semrush supplies the crawl issues. The Starlight repo supplies the tags. Semrush is a connection: POST /me/connections with type mcp, name semrush, url https://mcp.semrush.com/v2/mcp and auth mode oauth. The catalog says it is read only and spends your Semrush API units. Semrush's own docs list a discovery tool named site_audit, plus projects, and say the project methods exposed are the read-only ones from the Projects API v3. The session names the connection after status is connected. The docs site is a GitHub resource, one repository per run, cloned through the Rush GitHub App. The agent writes seo-audit.md and does not edit the tree.
The example is withastro/starlight. The docs app is docs/, Astro ^7.2.10, depending on @astrojs/starlight from the workspace. The published package version in packages/starlight/package.json is 0.42.6. The root packageManager is pnpm@11.22.0. docs/astro.config.mjs sets site to https://starlight.astro.build/ unless a Netlify preview URL is in the environment, trailingSlash to always, title Starlight, lastUpdated true, and an edit link whose baseUrl is the GitHub docs tree. Locales cover English at the root plus de, es, ja, fr, it, id, zh-cn, pt-br, pt-pt, ko, tr, ru, hi, da, uk and fa, and fa sets dir rtl. The head array in that config adds a Fathom script and og:image pointing at og.jpg on the site origin.
The tags a crawler sees are built in packages/starlight/src/utils/head.ts. getHead sets the title to the page title, the configured delimiter and the site title, unless the page overrides it. It emits a canonical link only when context.site is set, formatted by formatCanonical with the project's trailingSlash. It emits meta description from the page's description or the site description, og:title, og:type article, og:url, og:locale, og:description, og:site_name, and twitter:card summary_large_image. For a multilingual config it adds hreflang alternates for every locale plus x-default. When site is set it adds a link rel sitemap to /sitemap-index.xml. packages/starlight/src/integrations/sitemap.ts wraps @astrojs/sitemap and, if the site is multilingual, passes i18n.defaultLocale and the locale map. The schema in packages/starlight/src/schema.ts marks description as optional and says a good one is 150 to 160 characters.
The agent calls site_audit for starlight.astro.build and then attaches each issue type to that machinery. A canonical that drops or keeps the trailing slash is formatCanonical plus trailingSlash: 'always' in the docs config. A missing description is a docs page whose frontmatter omitted description, which the schema allows. A hreflang gap is getHead's loop over config.locales, or a missing translation under docs/src/content/docs. The English index sets template splash, turns lastUpdated off, and replaces the title with its own head entry, so a title issue on the home URL is that frontmatter. A sitemap issue is the integration's sitemap-index.xml. The Fathom script is the head entry in astro.config.mjs if the audit flags a third-party script.
Start it with one API call
POST https://api.prix.dev/o/{org}/sessions with this body:
{
"agent": "claude",
"input": "Use the Semrush connection and the site_audit tool to pull site-audit issues for https://starlight.astro.build/. The repository is in the sandbox. For each issue type, find the template that produces it. Read docs/astro.config.mjs, packages/starlight/src/utils/head.ts, packages/starlight/src/utils/canonical.ts, packages/starlight/src/integrations/sitemap.ts, packages/starlight/src/schema.ts and docs/src/content/docs/index.mdx. Write seo-audit.md with the issue, the pages affected, the file and line, and the fix. Do not invent issues the audit did not return. Change no code. Semrush is read only; do not try to create a project.",
"resources": [
{
"url": "https://github.com/your-org/your-app"
}
]
}- Get an API key. In the console, open Settings, then API keys, and create a key for your org. Send it in the Authorization header as a Bearer token.
- Send the request. POST the body in request.json to https://api.prix.dev/o/{org}/sessions, with your repository as the resources URL. The run starts in its own cloud sandbox.
- Read what came back. Follow the run on its live stream or wait for the run.completed webhook, then read the result and its trajectory.
What comes back
seo-audit.md comes back as an artifact: name, mime type, and a url on api.prix.dev that downloads the file with no key until url_expires_at. Read the session again for a fresh url, or GET /o/{org}/sessions/{id}/artifacts/seo-audit.md with the key. No file under docs/ or packages/starlight/ is modified. There is no pull request.
The report groups Semrush issue types. For each: the issue, the URLs, the file and line, and a fix written as text. Home-page title issues point at the head override in index.mdx. Description issues point at frontmatter or at the optional description in schema.ts. Canonical and trailing-slash issues point at head.ts and canonical.ts together with trailingSlash in the docs config. hreflang issues point at the locale loop and the locale key that is missing a page. Sitemap issues point at starlightSitemap and the link rel sitemap in getHead. An issue type that matches none of those is listed with the file left unknown.
A reviewer opens the cited line and checks it still emits that tag. Starlight merges page head over the defaults, so a fix in getHead does nothing for a page that already sets the same tag, and the report should say which layer it means. The transcript has the site_audit call and the file reads. Units are Semrush's.
Run it on every docs deploy
When the docs site finishes deploying, the pipeline POSTs this body to https://api.prix.dev/o/{org}/sessions. The Idempotency-Key is the deploy id, so a retry does not run site_audit twice. resources is the Starlight repository, or your fork, and the GitHub App installation has to cover it. Put the deployed origin in the prompt if it is not starlight.astro.build. One repository per session.
An admin session sets webhook_url on the key. Rush POSTs run.completed, run.failed or run.cancelled within about 30 seconds, signed with the whsec_ secret. Fetch seo-audit.md from the session artifacts. data.result is omitted past 16 KiB. Answer 2xx within 5 seconds or the same webhook-id is retried at 2, 4 and 6 minutes and then dropped. Read session_url if you miss it.
The use case this job follows, with its automation and trigger: Produce a report or file, no repo.
Why run it on Rush?
A Semrush row says a URL is missing a description or has a broken hreflang. In this repo the tag is not in the markdown file alone. Description text is frontmatter, the tag is getHead, the canonical slash is trailingSlash, and the alternate links are the locale map. The agent reads site_audit and those files in one sandbox, and the session keeps both, so the file in the report is the one that emits the tag.
Docs sites with many locales are a wide crawl and a wide tree. The run does that off your laptop, and a second site is a second session with its own sandbox, up to max_concurrent on the key (default 4, then 429). The sandbox parks at the end of the turn, costs nothing while parked, and stays for 7 idle days. A follow-up can expand one locale's hreflang rows from the transcript.
Frequently asked questions
Will it change frontmatter or open a pull request?
No. Change no code is in the prompt. The fix is a paragraph in seo-audit.md. Starlight's docs and the theme package are read. A follow-up run can apply one frontmatter description if you ask for a pull request then.
Semrush says the server is read only. Can the agent add the site to a project?
No. Semrush's docs say the Projects API methods on this server are the read-only ones, and the catalog says the same. site_audit reads an audit you already have. If starlight.astro.build is not in the connected account's projects, the report says the tool returned nothing, and it does not create a project.
Why does the home page not use the normal title template?
docs/src/content/docs/index.mdx sets a head entry for the title and uses template splash, with lastUpdated false. getHead's default title is for pages that do not override it. A title finding on the home URL has to cite the frontmatter head, or the fix will land in the wrong layer and the splash page will keep its own title tag.
Does a missing description fail the build?
No. schema.ts marks description as optional. getHead emits the meta description only when the page or the site config has one. A Semrush missing-description issue is a page that built fine and shipped without the tag. The fix is frontmatter, not a schema change, unless you want every page to require one.