Install
openclaw skills install @zhuyansen/backlink-guardCheck a link source before submitting a site to it, verify a listing after it goes live, and audit a site's own backlink profile for patterns that read as link spam. Use when the user wants to submit a site, tool or repository to directories, awesome lists or guest-post sites, asks whether a directory or link source is safe or worth it, wants to check whether a backlink is followed, asks for a backlink audit or spam check after a Google spam update, asks which sites link to their competitors and not to them, which sites Google's AI Overviews cite for their keywords, or what ChatGPT, Perplexity, Claude and Gemini answer, search for and cite when asked for what they make. Runs the backlink-guard command line; a GOANYAPI_API_KEY and a GLASSER_API_KEY (or an AISA_API_KEY) add the paid signals.
openclaw skills install @zhuyansen/backlink-guardFour jobs, in the order a careful person does them: find the pages your searchers already land on, check a place before you submit, check the link after it is live, and look at your own profile now and then. The tool gives signals with their evidence. It does not submit anything, and it is not Google's verdict.
uvx backlink-guard==0.11.0 <command> when uv is there, else pip install backlink-guard==0.11.0 and the backlink-guard command. Never run a clone of the repository's default branch. The commands below are written as backlink-guard; run them as uvx backlink-guard==0.11.0 …. Python 3.10 or newer, no dependencies. The log, the paid answers and the networks seen before are kept in ~/.backlink-guard (BACKLINK_GUARD_STATE moves them).GLASSER_API_KEY (https://link.glasser.ai/JasonZhu), the first choice: spam scores, Google search history, new and lost referring domains by week, anchors, competitors' referring domains, AI Overviews (cited).AISA_API_KEY (https://go.aisa.one/yansen-zhu), the second: the same when there is no Glasser key, and the only source of questions and asked, of --deep's Ahrefs rating and Semrush numbers, and of the site: search used when GoAnyAPI's fails.GOANYAPI_API_KEY (https://goanyapi.com/r/ga-95708898fb): a site's rating, a year of monthly visits, whether Google still lists it, and the summary of your own backlinks.
When the user has neither and wants the paid signals, suggest Glasser first, then AIsa. Without a key the page checks still run. Say which signals are missing: a site can pass the page checks and have no audience at all.find: about 0.005 USD a keyword (0.006 through Glasser) plus 0.012 USD for the search volumes, --vet then adds the vet cost. vet: about 0.01 USD a site plus about 0.16 USD for the batch (spam scores and search history), the same for one site or thirty, so put every site the user is considering in one call (one site about 0.17 USD in all, thirty about 0.46 USD); --deep adds about 0.19 USD a site (about 0.27 USD with an AIsa key, which adds Ahrefs' rating and Semrush's numbers), --recent 0.008 USD a site (and minutes). Before the user pays for any placement, run both. audit: about 0.12 USD, with --deep about 0.16 USD (plus about 0.035 USD when its backlinks name fewer than 300 referring domains). lost: about 0.06 USD, nothing more after an audit of the same site in the last 7 days. competitors: about 0.025 USD a call, 2N + 2 calls for N competitors (three: about 0.20 USD), never more than --max-usd (0.30 USD unless set); with --early about 0.06 USD a site, the user's included, plus about 0.025 USD a competitor for linking pages (one competitor and the user: about 0.08 USD; three: about 0.35 USD at most), never more than --max-usd (0.50 USD unless set), and its free vets of the first 10 checklist sites take a minute or two. vet --newcomers is free and adds 20 to 60 seconds a site. cited: 0.002 USD a keyword, 0.004 USD when the overview loads late (through Glasser 0.004 and 0.006 USD), never more than --max-usd (0.10 USD). questions: about 0.01 USD. asked: about 0.12 USD a question, --rank 0.0035 USD a search on each of Google and Bing, never more than --max-usd (1.00 USD). verify and log are free. Answers are cached for 7 days, so asking again costs nothing.backlink-guard find "claude skills" "claude code skills" --site yoursite.com --json
Start here when the user asks where to get links or listings. It reads Google's top 30 for each keyword and keeps the pages that are not the user's: directories, lists, articles, videos, threads, repositories. Each page has kind, ranks (keyword and position), visitors (monthly searches times the usual click share of that position: a size, not a count) and action. The pages are sorted by visitors: a page that ranks for the user's keyword sends people already looking for what they make, which is the point of a link.
list: ask to be added (a pull request to a GitHub list, a short note to an article's author).directory: submit, after vet. A GitHub topic page means adding that topic to the repository.article, video: an author or creator who covered the topic. Offer what the page lacks; a paid mention is marked as such.community: answer where it genuinely helps. Never drop links in bulk.docs, site: official pages and products; not sources.--vet vets the directories and the article sites found (not platforms like GitHub, Medium or YouTube, where the page and its author matter, not the platform's numbers). Use --skip for competitors.
backlink-guard competitors yoursite.com --vs competitor-a.com competitor-b.com competitor-c.com --json
For each competitor, new holds its referring domains first seen in the last --days days (7), strongest first, with the ones already linking to the user taken out (linking_you); shared holds the sites linking to two or more of the competitors and not to the user. Every row has site, rivals (which competitors it links to), rank (what its links pass, 0 to 1,000), first_seen, example (a linking page with its title) and kind with action, as in find. dropped names the sites left out (on the shared spam-link list, or links scoring 50 or more for spam) and networks the groups of three or more sites whose linking pages share one title, each with report, a filled-in report for the shared list. left_out names what the --max-usd cap did not ask: say it, and offer to raise the cap.
These are earned links: places that already cover the user's field. Suggest the honest move by kind (submit to a directory after vet, ask to be added to a list, offer an author what the page lacks). Never suggest buying a link, and vet a site before the user spends time on it.
backlink-guard competitors yoursite.com --vs competitor-a.com competitor-b.com --early --json
Use it when the user's site is new, or asks how competitors got started: the strong sites linking to a competitor today rarely take a new site, while what it got in its first weeks (directories, launch sites, lists, communities) mostly still does. Prefer competitors that launched near the user's own launch. sites holds, the user's first, each site's launch (day, from: archive or first link; dormant when the domain sat unused before; before_index when it is older than the backlink index, which begins 2019-01-15: then its earliest links are the index's first crawl, so say so and suggest a younger competitor), counts (referring domains 30, 60 and 90 days after launch, lost ones counted; exact: false is a floor) and bursts (weeks that brought five or more and three times the usual, with their sites: launch week, as a rule). For each competitor, rows are its first-90-day referring domains still live, followed and not site-wide, and rest counts the lost and nofollow-only ones and names the site-wide ones (mostly the owner's other sites or partners: never present those as channels). checklist holds what two or more competitors got early and the user lacks (with one competitor, its own rows), each with example, kind, action, young (the youngest competitor it linked to and at what age; recent when in the last half year: it still takes new sites) and vet (a free vet: grade, action, takes_new).
Lead with the same-age table: a new site compares itself with what its competitors had at the same age, not with their profile today. Then the checklist, best first: young.recent, then a directory or list kind, then what the free vet says; a skip or avoid stays out whatever the rest says. First seen is when the index found a link, not when it was placed.
backlink-guard cited yoursite.com "keyword one" "keyword two" --json
For each keyword (Google US, English): overview (whether there is an AI Overview), cited (the pages it cites), you (the user's pages among them) and rank (the user's organic position in the top 10, or none). sites tallies the sites cited across the keywords, most keywords first, with kind and action: the places where a mention can get the user into the answer. A keyword with overview: false has no AI Overview today: say that plainly, and do not call it "not cited".
backlink-guard questions "what the user makes, the way a buyer would put it" --plain > questions.txt
backlink-guard asked yoursite.com --file questions.txt --name "Their Brand" --rank --json
questions has ChatGPT, Claude and Gemini write the questions they expect; show them to the user and let them pick and edit before asked pays for answers. asked puts each question to ChatGPT, Google's AI Mode, Perplexity, Claude and Gemini. by_engine counts, per assistant, the answers that wrote the user's domain (named_you), gave only their name (name_only), cited them (cited_you) and named a site under their name with another ending (lookalike, never counted as the user's); sites and pages tally what was cited, with kind and action as in find; searches holds the searches the assistants ran.
With --rank, ranks looks each search up on Google and Bing (top 20): by_engine says how many searches were read and where the user ranks, each row of searches has you, your_page, lookalike and first_page per engine, sites puts the sites on the first page of the most searches next to cited (the answers citing them), and cited_elsewhere lists sites cited without ranking for any search read. Read it as a funnel: a site missing from the results of the searches is rarely read; a site that ranks and is not cited was passed over. A search with error failed twice and is not a search the user is missing from; left_out was over the cap.
Answers vary from one ask to the next: report counts with their denominators and call a change of one or two a fluctuation. Answers asked in the last 7 days come from the cache, so --rank after a run costs only the lookups.
backlink-guard vet mcpservers.org turbo0.com navi.tools --json
One call for all the sites the user is considering. Add --topic "their keyword" to see where each site ranks for it (fit): a site that ranks for the user's keyword is relevant by construction; mentions says its pages at least write about it. When they come as a list (a competitor gap export, a paid backlink list, a note), pass the file: --from list.xlsx --skip yoursite.com --skip competitors.txt. A run checks 30 sites unless --limit is raised; say the cost of a bigger run first. Each row has action (skip, look first, free only, low value, submit) with action_reason, grade (ok, caution, avoid: one avoid finding makes avoid, caution takes two caution findings), risk (3 for each avoid finding, 1 for each caution: use it to order sites with the same grade, not as a probability), reach (high, medium, low), metrics and flags; every flag has meaning, evidence and, where one applies, the line of Google's link spam policy it stands next to.
How to act on it:
action, and say action_reason in a sentence. skip: do not submit. look first: a check failed or the site refused it, it may be one of an operator's several sites, or two findings stand against it; read the evidence aloud and let the user decide. free only: a free listing is fine, but never pay for a followed link, never link back as a condition, never show its badge. low value: nothing against it, but under 1,000 visits a month; only if it costs nothing and fits. submit: none of these.networks in the result: one operator's sites that the shared spam-link list lacks, most of them flagged, each with report, a link to a filled-in report form for the list. Offer the link; opening it sends nothing, and only the user decides to submit it.listed finding: the site is on the shared list of spam-link sources (github.com/zhuyansen/backlink-spam-list), with the entry's evidence. If the user finds a network the list lacks, suggest reporting it there, with evidence anyone can check.avoid (dead, parked, not listed by Google, a URL shortener, a link network's template page, a link seller, or linking out to gambling and similar sites): do not submit. Lists of "the backlink sources other sites use" are full of these: they are there because people submit to them in bulk.caution: read the evidence aloud to the user and let them decide.policy (avoid, caution, clean: what a link there would mean under Google's link spam policies, one finding being enough) and value (high, medium, low, or none when nobody can reach the site). Give the user both, apart: a high-value site with a policy caution (paid_follow) is worth a free listing and never a payment; a site with value none is not worth the time, whatever else it says.ok with one finding under Why: one caution alone is not a verdict. Name it in a sentence; for paid_follow the free listing is fine, but never pay for a followed link.
paid_follow): the free listing may still be fine. Never pay for a followed link: a paid link must carry rel="sponsored" or nofollow.link_exchange): one is a choice; a habit of it is a link exchange.traffic_cliff): the evidence names the Google updates that ran around then. That is context, not proof of a penalty. Say it that way. A fall in the newest month of the data is only a note (traffic_drop) until the next month confirms it: in September 2026 one visits estimate halved for many sites whose Google traffic held. Say "check again next month", not "it was hit".search_fall, the last 12 months; old_search_fall is the same before that, a note): US Google traffic and ranking keywords fell together and have not come back, with the updates around then. Strong reason not to pay for a placement: Google already rates the site lower. Still context, not proof of a penalty, and US only: a site read mostly elsewhere can fall in the US and hold at home. When traffic_cliff fires on the same site, the two sources agree.scaled_pages): the site's own sitemaps list 1,000 or more pages for every keyword it ranks for on US Google. The shape of scaled, low-value content; on the test set most such sites were marked spam by Ahrefs. Not checked for sites in another language.hollow_rating): the rating was built with links. A listing there reaches nobody.spam_score): the site's own backlinks look manufactured.same_template): one operator's network, found in this check or against sites from earlier checks on this machine. Treat them as one site at most.same_owner): the same AdSense, Analytics, Tag Manager, Clarity or Facebook pixel account, in this check or an earlier one. One operator; treat them as one site at most.badge_network, with --deep): its rating comes from the badges every listed site must show. A listing there is a link exchange; never pay for it.unproven, with --deep): new, almost nobody links to it, almost nobody visits. Ahrefs marks most such sites spam. Free to submit if it costs nothing; never pay.not_indexing, with --recent): it keeps adding pages and Google shows none from the last 30 days. Say that site: counts are incomplete, and suggest checking again in a week before paying. inactive only means no new pages; it is not a fault. A failed search is reported as failed, never as zero.ok with reach: low: harmless and useless. Skip it unless it costs nothing.blocked note means the site refused the check: the page signals are missing, not clean.incomplete: it looked ok, but a check that could have found something failed (missing says which). Run it again before calling it ok.skipped: its own pages already put it at avoid, so no paid check was bought for it.newcomers (with --newcomers): whether it still takes new sites, read off its newest sitemap pages: pages read, sites they link to from their body, dated, young (registered within half a year before the page), share, newest (the newest page's day) and examples; unknown says why there is no answer (no dated sitemap, links through redirects or scripts). Say it as a sample: "2 of 7 sites its newest pages link to were registered in the half year before". None new is a reason to ask whether those pages are its listings, not a verdict; a stale newest (months old) means the site has stopped adding pages. It never changes the grade.What the check cannot see: a site that sells links privately and says nothing on its pages. In the test set, one of five media sites that publish contributed posts stated a fee; for the other four nothing could be read.
These are the rules Agent Skills Hub worked to. Follow them whatever the tool says.
gh command line), prepare the text and hand it to the user.backlink-guard log add mcpservers.org --kind directory --anchor "Agent Skills Hub" --url https://mcpservers.org/submit
backlink-guard log
backlink-guard verify https://mcpservers.org/servers/you/your-tool --to yoursite.com
backlink-guard log set mcpservers.org --status live --url https://mcpservers.org/servers/you/your-tool
Verdicts: followed link (passes ranking credit), qualified link (nofollow, sponsored or ugc: visitors only), redirect only (goes through the site's own redirect page: visitors only), not found, unreadable. Only those three rel values hold back credit; noopener and external do not. Each link also has a placement: body text, main area, header, navigation, sidebar, footer, comments or author box. Say where it is: a link an editor put in the body text is worth more than one in a footer or sidebar, and a followed link that appears only in a footer or widget across many pages is the template-link pattern Google lists as link spam. A link a script adds after load is not seen: the result says so, and a browser check settles it. If the user paid for a placement, compare what was promised with what is there.
backlink-guard audit yoursite.com --deep --json
It reports the totals, how many referring domains pass credit, new and lost referring domains by week, the anchors with the referring domains behind each, the site-wide links, and which of the top linking sites score high for spam. Every count of links comes with its count of referring domains: say both, and lead with domains. Flags:
velocity_spike: a week far above the usual. Ask what was done that week.anchor_repeat: one keyword anchor on a large share of links.spam_anchor: anchors that sell links or name gambling and similar trades. Someone else's network usually puts them there. Report it; do not alarm.spammy_referrers: several of the top linking sites score high for spam. If the user paid any of them, that is the lesson for next time.owner_network: three or more sites linking to the user report to one analytics or ads account (AdSense, Analytics, Tag Manager, Clarity, Facebook pixel, Cloudflare Web Analytics), read from their home pages (owners in the result, --homes caps how many, 0 skips). Say they count as one source. A media group's titles or a platform's hosted sites can share an account honestly; a network of casino or "mirror" sites cannot. Offer the report links of owners.networks; do not recommend a disavow file.sitewide (a note): one site links to one page of the user's from many of its pages (20 or more by default, --sitewide changes it), or from a few with most of them in its footer, sidebar or navigation. It is counted as one source in the anchor shares, and the output says so ("N links from 1 site, counted once"). Say it that way: a partner's footer link is common; it is the pattern Google describes only when it is placed for ranking.backlink-guard lost yoursite.com --json
From the same backlinks, it asks each page of the user's that gets links whether it is still there (free, four at a time) and lists the ones that answer 404 or 410, most referring domains first, each with the strongest referring domain and a suggest: the live page in the user's own sitemaps whose path is closest, with its score from 0 to 1, or no good match under 0.50. Any other error is blocked and no answer is unreachable: neither is dead, so do not call them lost. Present the list as suggestions for permanent (301 or 308) redirects, the user's call page by page; the tool redirects nothing, and a suggestion with a low score or a different subject is better left as a 404 or pointed at a parent page the user picks.
redirected holds the pages of the user's that redirect, followed hop by hop, each with a verdict, worst first, and why: broken (a loop, more than ten hops, or no page at the end), soft_lost (it ends on the home page, on another site or on an unrelated page: Google may treat that as a soft 404; suggest holds the closest live page as for a dead one), temporary (a 302, 303 or 307 on the way: Google keeps the old URL), chain (two hops or more) or fine. A soft-lost verdict comes from paths: a renamed page can be fine, so ask before changing a redirect.
Google ignores most junk links rather than punishing them. Do not recommend a disavow file unless the user has a manual action for links in Search Console.
backlink-guard recheck --to yoursite.com --json
It checks the sites in the log (submitted or live) again and compares them with the last look: a lower verdict, a new finding against a site, and with --to a link of the user's no longer found. Report only what got worse, with its evidence. A site that turned avoid (parked, dropped by Google, carrying an injected checkout link) is one to stop sending people to; Google ignores most bad links, so asking for removal is rarely needed. It only works if the log is kept: log add after every submission.
If the user has analytics, ask for the referral export (GA4: Reports, Acquisition, Traffic acquisition, by Session source, exported as CSV) and pass it to vet with --referrals. sent_you is what each site really sent: on one young site, 10 of the 14 sites rated high reach had sent visits in 30 days, 2 of the 37 rated low.
find: the keywords with their searches, then the pages worth being on, busiest first (page, kind, where it ranks, visitors, what to do), then the five or so the user should act on this week and how. Say plainly that visitors are an estimate of size.vet: a table (site, action, verdict, reach, rating, visits a month, spam score, fit when --topic was given, why), then each flagged site's evidence, then what was not checked and why (missing key, failed source, blocked site), then a short recommendation: where to submit first, what to skip, and the report links of any networks.audit: the numbers, the findings with evidence, and at most three things to do.lost: the dead pages with their referring domains and the suggested 301 targets, the ones with no good match apart, then the redirects that lose something (broken, soft-lost with its suggestion, temporary, chain), then what was blocked or unreachable.competitors: per competitor the new sites worth a look, then the sites linking to several competitors and not to the user, each with its linking page and the honest move; then what was left out and why, and the cost.competitors --early: the same-age table with each launch day and where it came from, the bursts with their sites, then the checklist (site, which competitors, first seen, linking page, kind, took a new site, free vet) and the five or so to act on first; then the site-wide, lost and left-out counts, any before_index competitor, and the cost.cited: per keyword whether there is an AI Overview and whether it cites the user, then the sites cited most and what kind of page each is.asked: a table per assistant (answers, domain written, name only, cited, same-name site), the sites cited most with what to do there, and with --rank where the user ranks for the assistants' searches and which ranking sites were cited; then the cost.