Veriguard

npm packages

Scam detection as a dependency

Two packages, one engine. Install the library to score messages inside your own product, or run the MCP server so your AI assistant can check things for you. Both are rule-based, both run locally, and neither needs an API key.

The library

Import it and call a function. No API key, no service to reach, nothing sent anywhere — the engine has no ambient network access, so with no transport supplied it cannot make a request at all.

score messages in your own code, or from your AI assistant

Install

npm install @veriguard/detect

Check one thing

Every entry point returns a verdict, a score out of 100, and the reasons behind it.

import { checkUrl } from "@veriguard/detect";

// Synchronous: no I/O, so there is nothing to await.
const result = checkUrl("https://commbank-secure-login.tk/verify");

result.verdict; // "likely_scam"
result.score;   // 85
result.flags;   // why, in sentences you can show someone

Check arbitrary text

Hand it a whole message and it returns one result per link, phone number or address it finds.

import { analyzeContent } from "@veriguard/detect";

// One result per link, number or address found in the text.
const results = await analyzeContent(
  "Your parcel is held. Pay the fee at auspost-redelivery.bond",
);

for (const { kind, value, result } of results) {
  console.log(kind, value, result.verdict, result.score);
}

What comes back

The part worth building on is the evidence, not the number. Each signal carries the sentence a person reads and the points it contributed, so your interface can explain a verdict rather than assert it.

verdict
One of safe, suspicious, likely_scam or unknown.
score
0–100. Higher is worse.
flags
The reasons, as plain sentences.
signals
The same reasons carrying their weights and which surface they came from.
coverage
How much of the region's rule set applied. Read the warning below.

Read this before you render a verdict

Detection coverage varies by region. When coverage is anything other than full, a low score means “no rules matched” — not “this is safe”. Showing a confident all-clear on a partially covered result is the one misuse of this package that puts someone at risk, because a false reassurance is worse than no answer at all.

Check result.coverage and soften your wording when it isn't full.

Regions

Rules are grouped into per-country packs on top of a shared base. Pass a region code to pick one; the packs are data, and the scoring logic is the same everywhere.

import { checkSms } from "@veriguard/detect";

// Region is the third argument. The second is an optional blocklist —
// pass undefined to score without one.
checkSms("Your parcel is held", undefined, "gb");

The MCP server

Gives your AI assistant four scam-checking tools. Your assistant decides what to say about a result; it has no part in producing one — the scoring is the same rule-based engine, so a model that is wrong about a link cannot make the verdict wrong.

Runs on your machine over stdio. Nothing to install first — npx fetches it on demand.

Add it to your client

Claude Code

claude mcp add veriguard -- npx -y @veriguard/mcp

Other MCP clients

Most clients take a JSON config naming a command to run.

{
  "mcpServers": {
    "veriguard": {
      "command": "npx",
      "args": ["-y","@veriguard/mcp"]
    }
  }
}

The tools

All four take an optional region code. Pass the user's country when you know it — the rules for impersonated banks, government services and phone formats are country-specific.

check_message
Any pasted text. Finds every link, address and number in it and scores each, plus the wording. The right default.
check_url
A single link.
check_phone
A number that called or texted.
check_email
An email, ideally with full headers.

What it contacts

Two hosts, both fixed, neither of them a host from what you are checking. The content you check is never sent anywhere, and a link you check is never visited — it is read as text. Expansion contacts the shortener only and stops before the destination, so a scam link is never reached.

Both flags together leave the server with no network access at all.

npx -y @veriguard/mcp --no-blocklist --no-expand

Full documentation

Every entry point, every tool, the type definitions and the build notes live with the source.