Finds images, avatars, fonts and embeds in your docs that are hotlinked from non-EU hosts, so EU visitor IPs leave the EEA before anyone consents. Runs entirely in your browser — nothing is uploaded.
Same engine as the VS Code extension, byte for byte.
Free for the file open in your editor - no key, no limit. The workspace sweep and the report ask for a key.
VS Code MarketplaceOpen VSX (Cursor, VSCodium)npmMCP server (npx)Docker Hubext install ReadyStack.image-host-transfer-lint npx @readystack/image-host-transfer-lint <file> npx @readystack/image-host-transfer-lint --mcp
Team? One key for every ReadyStack linter, 5 seats, $149 once
Workspace-wide export: an Art. 30 transfer register (CSV + Markdown) plus a self-host rewrite map for every file, per team seat.
One payment, one licence key for this tool. The key is shown right after payment.
LG Munchen I, 20 O 14144/19 (2022-01-20) awarded EUR 100 in damages to one visitor for one Google Fonts call on one page.
Buy the full version — $29· ReadyStack
Real numbers from this tool, line by line.

Seven assets on one 41-line deploy handbook page send EU visitor IPs outside the EEA before the page has finished loading, and every one of the seven is fixable inside the repository - that page is the bundled test fixture of Image Host Transfer Lint, written the way a German platform team writes an internal handbook that later goes public.
A docs page reads like text. It is not. Every screenshot, every avatar, every build badge and every webfont link is an instruction to the reader's browser: go and fetch this from somebody else's server. The fetch carries the reader's IP address, the page they are reading, and the time. When the server is outside the EEA, that is a transfer to a third country under GDPR Art. 44, and it happens while the page renders - before a consent banner exists, before the reader has clicked anything, on every visit.
The German courts have already put a number on it. LG Munchen I, case 20 O 14144/19, decided on 20 January 2022, awarded one visitor EUR 100 in damages for a single Google Fonts call on a single page.
Run the engine over the dirty fixture and it returns 7 findings on 7 lines: 6 errors and 1 warning. The stylesheet comes from fonts.googleapis.com. The maintainer photo comes from secure.gravatar.com, which also carries the MD5 hash of an e-mail address. The dashboard screenshot is hotlinked from i.imgur.com. The queue-depth panel sits on i.loli.net, the SM.MS image host in China. The build badge is a live image from img.shields.io. The walkthrough is a plain youtube.com/embed iframe. The copy helper is a script tag pointed at cdn.jsdelivr.net.
Run it over the clean fixture - the same page after the fixes - and it returns 0.
The interesting part is the third column: the country. This is where people, and chatbots, get it wrong. raw.githubusercontent.com feels like "my own repo" and is a host in the United States. cdn.jsdelivr.net is not one country at all; it resolves to US and Chinese edge nodes depending on who is reading, so there is no single receiving country for an Art. 30(1)(e) record. China has no EU adequacy decision, so an image on a Chinese bucket needs standard contractual clauses and a transfer impact assessment. Images land there constantly: an upload plugin ships with a default backend, somebody presses paste, and the link outlives the memory of it.
Seventeen rules cover the families that actually show up in docs repositories: webfonts, avatars, image hosts, repo hotlinks, script CDNs, Chinese object storage, embeds and comment widgets, live badges and diagram render services, analytics that fire on render, and assets still fetched over plain http.
Two things it deliberately does not count: a hostname written in prose, because prose makes no request, and anything inside a fenced code block, because an example is documentation. The clean fixture keeps the old leaking markup inside a fence on purpose, and still scores zero.
That is also the answer to "why not a free online scanner". A scanner loads a URL that is already published. It cannot see the Markdown on your branch or the pull request adding the next Imgur link. The lint runs where the text lives, so the leak is caught by review instead of by a visitor.
The free scan finishes one job completely: open a file or a folder, and every leaking asset is named with its host, its country and its fix. The next job is a different one - owning the evidence: an Art. 30 transfer register exported as CSV and Markdown for the whole workspace, plus a self-host rewrite map listing every file, every URL and the local path that replaces it.
It reads your Markdown, MDX and HTML docs line by line and flags every asset URL a reader's browser would fetch from a third party: webfonts, avatars, image hosts, script CDNs, embeds, live badges and analytics. Each finding names the host, the country the request lands in, and the concrete fix that keeps the asset on your own origin.
Developers and technical writers in Germany, Austria and the Netherlands who publish a docs site out of a Markdown or HTML repository. If your handbook, changelog or product docs are public and your readers are in the EU, every hotlinked asset on those pages is a transfer you are answerable for.
Online privacy scanners load a rendered URL. They cannot see the Markdown in your repository, the pages you have not deployed yet, or the branch under review. This runs where the text lives, so a leaking image is caught in the pull request instead of after publication, and code blocks holding examples are not counted as leaks.
The free scan is complete on its own: open a file or folder and every leaking asset is named with host, country and fix. The paid layer is a different job - owning the evidence. It exports a workspace-wide Art. 30 transfer register as CSV and Markdown plus a self-host rewrite map, and covers a team seat.
A court has already priced the failure: LG Munchen I, case 20 O 14144/19, awarded one visitor EUR 100 in damages on 20 January 2022 for a single Google Fonts call on a single page. A manual review of a docs repository is billed as privacy counsel time, page by page, and has to be repeated after every merge.
A general AI chat answers from training data with a cutoff date, cannot read your repository and names no rule version. Image Host Transfer Lint checks the file you open against 17 rules from a rule set dated 2026-09-21, and points at the exact line. For a filing, an audit or a client you need that dated result on your own files.
One question, answered by the person who built it. Your email only if you want the answer sent.