link-checkup
Checks URLs and domains against abuse.ch's URLhaus blocklist, flagging known malicious entries as critical in the link risk report.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@link-checkupCheck this suspicious link for risk: http://paypa1.example/login"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Link Checkup · 可疑链接体检
Check a suspicious link — without opening it. Paste a URL from a text, email, chat or QR code and get a 0–100 risk score, per-check findings and a one-sentence verdict in English and 简体中文. The page is never rendered, no JavaScript runs and nothing is downloaded.
Built for the Kiro University Challenge 2026 final exam. Uses only free, keyless data sources.

The problem
I get links I don't trust all the time — "your parcel is on hold", "verify your account", a friend's hacked account sending "is this you in the video?". My habit is to forward them to an assistant to screen them before anyone clicks, so my phone, laptop and accounts are never exposed. Opening a link "just to see" is exactly what the attacker wants: it can fingerprint the device, trigger a download, or show a pixel-perfect fake login.
Link Checkup turns that screening into a repeatable tool. It answers who really owns this link, how old is it,
where does it really go, and is it already known to be bad — using only DNS, a TLS handshake and HTTP
headers. It works as a web page, a CLI, an MCP server, and a Kiro custom agent (link-triage) that
screens links on my behalf.
Related MCP server: Malicious Scanner MCP Server
What it checks
Check | How (free, no API key) | Example signals |
Public blocklists | URLhaus online-URL text feed + Phishing Army domain list, cached 1 h, string-matched only | listed URL / domain → critical (score ≥ 90) |
Lookalike / typosquat | Local: confusable-character skeletons, Damerau–Levenshtein, combosquat, brand-in-subdomain, mixed scripts / punycode vs. 49 brands |
|
Domain age & registrar | RDAP ( | registered < 30 days, registry hold |
Redirect chain |
| cross-site hops, https→http, |
TLS certificate | Bare TLS handshake (SNI), no HTTP request | invalid / expired / mismatched cert, issued < 7 days |
DNS | DNS-over-HTTPS (Cloudflare → Google fallback) | NXDOMAIN, resolves to private IPs |
URL structure | Local parsing | raw IP, |
Safety design (see network-safety.md):
every connection to a user-supplied host goes through src/net/safeRequest.ts:
all resolved IPs must be public unicast (loopback, RFC1918, link-local, CGNAT, ULA, IPv4-mapped/NAT64/6to4
forms are refused), the vetted IP is pinned to defeat DNS rebinding, only ports 80/443 are contacted,
response bodies are never read. Unknown results (timeouts, errors) add 0 points — unknown ≠ dangerous.
Scoring (src/scoring.ts): sum of finding points clamped to 0–100; any critical finding
forces ≥ 90; levels: low < 25 ≤ medium < 60 ≤ high. These invariants are enforced by property-based tests.
Run it
Requires Node.js ≥ 20.
git clone https://github.com/kosermuy-maker/link-checkup && cd link-checkup
npm install
npm start # → http://127.0.0.1:8787 (English / 中文 toggle)CLI and MCP:
npm run check -- "hxxp://paypa1[.]example/login" # defanged input is fine
npm run check -- https://example.com --lang zh
npm run check -- https://example.com --json
npm run check -- paypa1.example --offline # local checks only, no network
npm run mcp # stdio MCP server (check_url, check_lookalike)
npm run mcp:smoke # spawns the MCP server and calls both tools
npm test && npm run typecheck # 77 unit + property-based testsAPI: POST /api/check with {"url": "..."} → JSON report (8 KB body limit, 30 checks/min per client).
Demo safely. Use benign domains (
example.com,github.com) and synthetic lookalikes on reserved TLDs (paypa1.example,secure-paypal-login.test). Never paste real phishing links into demos or tests.
Deploying is optional (it's a plain Node server; any free Node host works). It is designed to run locally.
Hooks not firing or MCP panel empty in Kiro? See docs/kiro-troubleshooting.md: trust the workspace, then Reload Window.
How each Kiro lesson is used
# | Lesson | Where | How it is used |
1 | Spec-driven development |
| 11 requirements with EARS acceptance criteria (e.g. "WHEN a Target hostname resolves to any address that is not a Public address THE System SHALL refuse to connect"), a design with architecture + sequence diagrams, and a task plan whose items reference requirement numbers. Git history follows the task list. |
2 | Steering |
| Encodes the product promise ("never open the page"), the stack and hard rules (all target traffic via |
3 | Hooks |
| |
4 | Property-based testing |
| Score bounded / monotonic / critical ≥ 90 / level partition; no false positives on any official brand subdomain; every single-character homoglyph substitution of a brand is caught; edit-distance metric laws; every private IPv4/IPv6 (incl. IPv4-mapped) is blocked; URL normalisation idempotent; redirect following terminates for any random redirect graph. Each test is tagged with its property and the requirement it validates. |
5 | Powers |
| The checker packaged as an Agent-Plugins power: keywords like "phishing", "suspicious link", "可疑链接" activate it; its MCP server is launched with |
6 | MCP |
| Project MCP server exposing |
7 | Custom agents |
|
|
★ | Bonus: Package a Kiro power | Validated against the Agent Plugins 1.0.0 |
Project layout
src/ engine (checks, net guard, scoring, explain), server, CLI, MCP server
public/ static bilingual UI (no build step)
test/ vitest unit tests + fast-check property tests
powers/ Kiro power package
.kiro/ specs, steering, hooks, settings/mcp.json, agents, skills
scripts/ hook helpers, MCP smoke test, screenshot scriptScreenshots
|
|
|
|
Screenshots were produced headlessly with Playwright (scripts/screenshots.mjs) against the local server.
Limitations
A low score is not a guarantee; brand-new attacks may not be on blocklists yet.
The brand list is curated (49 brands) and typosquat detection can flag legitimate look-alike names (e.g.
chaser.com) — findings explain why, and the score is only a guide.RDAP coverage varies by TLD (some ccTLDs don't publish RDAP); that check then reports "not checked".
Phishing Army's list is CC BY-NC 4.0: it is downloaded at runtime, not redistributed.
License
This server cannot be deployed
Maintenance
Related MCP Connectors
URL intelligence for AI agents and developers. 16 tools, 25 signal weights, 20 free checks.
AI URL safety validator: SAFE/SUSPICIOUS/DANGEROUS verdict, trust score, threat intel.
AI-powered scam and threat verification for phone numbers, URLs, texts, and emails.
Scam and phishing detection for AI agents: safe/warn/danger verdicts for URLs and messages.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceValidates URLs and checks their reputation to help identify AI hallucinations and verify web page authenticity.MIT
- AlicenseBqualityDmaintenanceEnables real-time scanning of URLs for malicious content, spam/gray classification, and additional security flags like domain age through the Malicious Scanner API.1MIT
- AlicenseAqualityAmaintenanceEnables AI agents to check URL safety before fetching content, using Google Web Risk, URLhaus, PhishTank, and AI analysis to return SAFE/SUSPICIOUS/DANGEROUS verdicts.138 npm1MIT
- AlicenseNot gradedqualityBmaintenanceEnables checking URLs against the PhishTank phishing database to identify malicious sites.4 npmMIT


