Skip to main content
Glama

URLVerify_MCP · Source-Verification MCP Server / 來源驗證 MCP Server

A small investigative agent exposed as an MCP server: given a download / installer / repo / model URL, it decides whether the source is official. 一個以 MCP server 形式提供的小型調查 agent:給定下載、安裝包、倉庫或模型網址,判斷來源是否官方

Verdicts VERIFIED_TRUE · VERIFIED_FALSE · UNVERIFIABLE, each with a confidence score, a reason in the caller's language, and evidence whose quotes are verified against fetched content. 判定為三態,各附信心分數、跟隨呼叫方語言的結論,以及可逐字驗證的證據。

Configuration reference: every config.yaml field is explained in document_for_config.md. 設定說明:所有 config.yaml 欄位的解釋見 document_for_config.md

How it works / 運作方式

  1. L0 — deterministic checks (no LLM): TLS chain / SAN / Organization, DNS, redirect chain, punycode / homoglyph / typosquat / subdomain abuse, Certificate-Transparency first-seen, platform anchors, allow/deny lists, prompt-injection screening of the target page. 確定性檢查(不經 LLM):TLS、DNS、重導鏈、同形字/仿冒網域、CT 首見時間、平台錨點、黑白名單、目標頁注入篩檢。

  2. L1 — identity resolution (LLM + tools): product → developer → aliases → official domains / orgs, backed by tiered independent third-party sources with temporal-stability checks. 身分解析(LLM+工具):產品→開發者→別名→官方網域/組織,需多個分級獨立第三方來源佐證,並檢查時間穩定性。

  3. Rules engine: verifies every quote, counts independent sources, matches the target against the established identity. The LLM proposes; the rules decide. 規則引擎:驗證引文、計算獨立來源數、比對目標與官方身分——LLM 提議,規則裁決。

Related MCP server: c2pa-mcp

Quick start / 快速開始

Requirements: Python ≥ 3.11 (or uv, preferred) and an OpenAI-compatible LLM endpoint (llama-server, LM Studio, vLLM, Ollama, OpenAI…). Web search is optional but recommended: a SearXNG instance with its JSON API enabled (search.formats: [html, json]). Page fetching is built in; nothing else needs to be installed.

Linux / macOS

Step

Command

What it does

1. Install

./setup-venv.sh

Creates .venv with uv (uses uv.lock) or falls back to python -m venv + pip. Re-run any time; the old .venv is backed up.

2. Configure

cp config.example.yaml config.yaml

config.yaml is git-ignored and machine-specific. Edit at least the three endpoints below.

3. Probe

uv run urlverify-mcp check-env

Confirms the LLM answers /v1/models and the search backend returns results. Fix these before going further.

4. Run

see Running below

Admin UI, MCP server, or a one-shot verification.

Without uv, replace uv run urlverify-mcp with .venv/bin/urlverify-mcp in every command.

Windows

Step

Command (PowerShell)

What it does

1. Install

.\setup-venv.ps1

Same as the shell script: uv if present, otherwise venv + pip. A .venv copied from Linux is detected and moved aside.

2. Configure

Copy-Item config.example.yaml config.yaml

Then edit the endpoints below.

3. Probe

uv run urlverify-mcp check-env

Same probe. Without uv: .venv\Scripts\urlverify-mcp check-env.

4. Run

see Running below

Windows notes:

  • No SearXNG at all? Set search.provider: none: the investigator then relies on the structured sources only (Wikidata, Wikipedia, Wayback, GitHub, Hugging Face, registries). Well-known projects still verify; obscure ones come back UNVERIFIABLE more often.

  • Keep console output UTF-8 (chcp 65001) so non-ASCII reasons render correctly. Logs are plain text (no ANSI colours) on every platform.

  • In config.yaml, write Windows paths with forward slashes or in single quotes ('C:\\tools\\logs'); inside double quotes YAML treats \ as an escape character.

  • A launcher must not pass --transport unless it means to override config.yaml; CLI flags win over the config file.

The three endpoints in config.yaml

llm:
  base_url: "http://127.0.0.1:8080/v1"   # any OpenAI-compatible server
  model: "your-model-id"                  # some servers ignore this and serve whatever is loaded

search:
  provider: searxng_http                  # searxng_http (default) | mcp (SearXNG MCP server) | none
  searxng_http:
    base_url: "http://127.0.0.1:8888"     # SearXNG JSON API

fetch:
  provider: builtin                       # builtin (default, no dependencies) | mcp

server:
  transport: stdio                        # stdio | http  →  http://host:port/mcp
  port: 8766
admin:
  port: 8765

Running

Goal

Command

Notes

Admin UI

uv run urlverify-mcp admin

http://127.0.0.1:8765 — config editor, allow/deny lists, caches, history, manual test.

MCP server (stdio)

uv run urlverify-mcp serve

For hosts that spawn the process themselves (Claude Desktop, Claude Code, …). Nothing is printed; that is expected.

MCP server (HTTP)

uv run urlverify-mcp serve --transport http

Streamable HTTP at http://127.0.0.1:8766/mcp for URL-based hosts (LibreChat, …). Set server.transport: http to make it the default. Browsers show 400/406 on this URL; test with a POST.

Long verifications and client timeouts: the server sends MCP progress notifications at every step plus a heartbeat (server.progress_events, server.heartbeat_s), so clients that honour resetTimeoutOnProgress never hit -32001 however long a run takes; every wait is bounded and the whole run by budget.max_total_s. OpenCode honours progress since its June 2026 fix (PR #32477); older builds time out regardless of what the server sends. | One-shot check | uv run urlverify-mcp verify "LM Studio" https://lmstudio.ai/download "Linux AppImage" | Prints the full JSON result. Exit code 0 only for VERIFIED_TRUE. |

MCP host configuration:

// stdio — the host launches the server
{ "mcpServers": { "urlverify": {
    "command": "uv", "args": ["--directory", "/path/to/urlverify-mcp", "run", "urlverify-mcp", "serve"] } } }

// HTTP — the server is already running with --transport http
{ "mcpServers": { "urlverify": { "url": "http://127.0.0.1:8766/mcp" } } }

Recommended system prompt for the calling agent. The tool description explains what verify_source does; when an agent must use it is policy, which belongs in the host's system prompt. Suggested wording:

Regardless of the source, before downloading any executable, source code, library, or script, you MUST verify its URL using URLVerify_MCP. If the verification does not pass and no other usable source is available, you MUST report the issue to the user and ask for permission before proceeding. If URLVerify_MCP is unavailable, you MUST report this to the user and obtain permission before downloading or installing anything.

Tool exposed: verify_source(project, url, description, options?){verdict, confidence, reason, evidence[], checks{}, identity{}, risk_signals[], trace_id}.

Full data log & editable prompts

Feature

Where

Notes

Full data log

full_log.enabled in config.yaml, or the switch at the top of the admin Config tab

Off by default. Records, in order, every MCP request/response, every LLM turn (request messages, response, and the model's reasoning when the backend returns it), every search/fetch exchange, structured API results, L0 results and the rules decision, as one JSON record per line. Files are full-YYYYMMDDHHMMSS.log in full_log.dir; a new file starts once the current one exceeds max_bytes (1 MB). Browse them in the admin Logs tab.

Agent prompts

admin Prompts tab → agent_*

The investigator's system prompt, the submit_verdict schema text, the fallback JSON-action instructions and the final reason-writing prompt. Edits are saved as overrides in prompts.dir and take effect on the next verification.

MCP-facing prompts

admin Prompts tab → mcp_*

The server instructions and the three tool descriptions shown to the agent that calls this MCP server. Registered at startup, so restart serve after editing.

Defaults ship in urlverify_mcp/prompt_defaults/; Reset to default deletes the override. Required placeholders (e.g. {findings} in the reason prompt) are validated on save.

Registry fast path (PyPI / npm)

A package URL (pypi.org/project/<name>, npmjs.com/package/<name>) asks a narrower question than a website: is this the real package, published by the project it claims? Registries answer the second half themselves: build provenance — npm's Sigstore attestations and PyPI's PEP 740 provenance — is the registry's signed statement of which repository's CI published this version. A name-squatter cannot forge one naming someone else's repository. VERIFIED_TRUE (confidence package_registry_fast_path.confidence, path: registry_fast_path) requires all of:

  • the package exists, its first release is older than min_age_days, and it has min_releases releases;

  • signed provenance for the latest version, whose repository owner is a domain-verified GitHub organisation (deps.dev's independent verification of the same attestation is recorded when available);

  • the registry metadata and that repository's manifest (pyproject.toml / setup.cfg / setup.py, package.json) agree on the package name (bidirectional link), and the repository is not a fork;

  • for scoped npm packages (@scope/name) the scope equals the provenance repository's owner — the scope is the identity;

  • for PyPI, no far more popular package one edit away on the popularity list (popularity is only the denominator). npm has no such reference, and guessing "likely typos" is guesswork (nobody sees their own typos), so npm relies on provenance alone;

  • the caller's project name matches the package or the owner.

A name the registry itself has disowned — an npm security holding package (0.0.1-security, the name of a removed malicious package) — is VERIFIED_FALSE outright; a PyPI release whose files are all yanked is a risk signal. Packages without provenance (most small or dormant ones) are not trusted on metadata alone: they go through the full investigation, and without independent evidence come back UNVERIFIABLE. That is deliberate — a new or small package has not earned trust, and the calling agent should ask the user. In the full investigation, provenance also lets a package inherit the standing of an established GitHub organisation. options.mode = auto (default) | quick | full.

Where things live

<project>/
  config.yaml            machine-specific settings (relative paths below resolve against this file's folder)
  state/                 rebuildable caches and settings: cert_cache.json, identity_cache.json, pypi_top.json,
                         admin.auth, prompts/ (edited prompts). Safe to copy to another machine or hand to someone.
  log/                   records of what this installation did: full/ (full data log), history/ (one JSON per
                         verification + index.jsonl), health.json (observed dependency health), server/ and admin/
                         (process output incl. "!! DEPENDENCY" lines, rotated). May be private; delete freely.

No database, no files outside the project folder. Both folders are git-ignored.

Security notes

  • DNS spoofing and TLS interception. The trusted-certificate requirement already defeats plain DNS poisoning (an attacker's server cannot present a valid certificate for the host). Two checks cover what remains: the leaf certificate must be publicly logged in Certificate Transparency (net.ct_check) — a locally installed interception CA never is — and the host is resolved again over DNS-over-HTTPS (net.doh_cross_check); when the answers differ, a handshake against the DoH address tells GeoDNS apart from a poisoned local resolver. No IP lists are bundled.

  • Non-public targets are refused. Loopback, private, link-local and .local-style hosts, and redirects that land on them, fail L0 with public_address and never get probed. A verification server should not be usable for LAN reconnaissance.

  • Admin UI: password-only login (default admin, change it in the UI). The hash (PBKDF2-HMAC-SHA256, random salt) and the session-signing key live in admin.auth_file; delete that file to reset. Sessions last admin.session_days. The UI can edit the config, open folders and run verifications: keep it on 127.0.0.1 and closed when not in use.

  • HTTP transport: no authentication unless server.auth_token is set, in which case every request must carry Authorization: Bearer <token> (most MCP hosts accept custom headers per server). Default bind is 127.0.0.1.

  • Concurrency: server.max_concurrent (default 1) queues extra verify_source calls so a local LLM is never hit twice at once.

Threat model & limitations

What it is good at: look-alike domains (homoglyph, typosquat, brand-in-label, subdomain abuse), non-official orgs on hosting platforms (forks, community re-uploads, wrong GitHub / Hugging Face owner), non-existent or typosquatted packages, pages that try to talk to AI agents, plain-HTTP or untrusted-certificate downloads.

What it does not do: it never downloads or inspects the file itself (no hash, signature or malware check); it does not prove a site is safe, only that it is the project's own channel; UNVERIFIABLE means "not enough independent evidence", not "dangerous". Results depend on the LLM you point it at and on third-party services (Wikipedia, Wikidata, archive.org, GitHub, registries) being reachable and rate-limit friendly.

Known weak spots: very new projects and projects without a Wikipedia / Wikidata presence tend to come back UNVERIFIABLE (a design choice: absence of independent evidence is not evidence); dynamic download pages may show a different OS's link than the one described; tier-3 sources only count when their age can be proven, so a project known only from forums stays unverifiable; Reddit dating uses the public RSS feed, which lacks the edit timestamp.

Data flow (what leaves your machine)

Project name and URL go to the search engines behind your SearXNG, to Wikipedia / Wikidata, archive.org, GitHub, Hugging Face, PyPI / npm, crt.sh, deps.dev, the DoH resolvers in net.doh_resolvers (host names only) and (for tier-3 dating) Reddit / HN / Stack Exchange as needed. Fetched page text and the investigator's messages go to the LLM endpoint you configured: with a local model nothing else leaves; with a cloud API the provider sees them. Nothing is sent anywhere else, and no telemetry exists.

Network footprint

The agent never renders pages: it requests the HTML/JSON document only, so images, CSS, scripts and fonts are never downloaded. Other measures that keep traffic small and polite: redirect chains are walked with HEAD (a GET is streamed and closed immediately if HEAD is refused); files under verification are never downloaded (binary content-types are reported, not read); page bodies are capped at 2 MB and truncated to budget.fetch_max_chars before the LLM sees them; per-verification budgets (budget.max_searches / max_fetches / max_api_calls) bound the number of requests; certificates and resolved identities are cached (cache.*); Wikipedia / Wikidata / GitHub / Hugging Face / registries are queried through their JSON APIs instead of scraping; Reddit requests are serialized; and net.user_agent identifies the tool with a contact URL, which Wikimedia requires.

Tests / 測試

Suite

Command

Needs

Time

Unit

uv run pytest -q

nothing (offline)

seconds

Pipeline (scripted LLM, real network)

included in uv run pytest -q; auto-skips when offline

network

~1 min

Live regression

uv run pytest tests/test_live.py --live -s

LLM + search + network

10–15 min

uv run urlverify-mcp check-env (or the Run check-env button on the admin Status tab) probes only the endpoints you configured — LLM /models, SearXNG /healthz (or the MCP handshake), the fetcher — and is never run automatically. Public third-party services are not probed at all: for a service that stays up for days a probe is only a snapshot, so their state is the observed dependency health table (admin Status tab, /api/health): every real call records its outcome, failures print a prominent !! DEPENDENCY … line on stderr and a dependency_failure record in the full log, and each result lists the dependencies that failed during that run in degraded. The table is a report, never a gate: networks flap, and the next call is always attempted. Results carry schema_version (currently 1); a breaking change to the result shape bumps it.

Windows without uv: .venv\Scripts\python -m pytest -q (same flags).

The unit suite covers URL/homoglyph analysis, the rules engine (quote verification, source counting, tier promotion by age, temporal contradictions), injection detection, and the search provider's failure handling. The live suite runs the cases in tests/fixtures/cases.yaml; every check family has at least one true and one false case, and any change to prompts or rules should be validated against it.

Docs & license / 文件與授權

  • AGENTS.md — design charter: interface contract, source tiering, safety red lines (Traditional Chinese). / 設計憲章:介面契約、來源分級、安全紅線(繁體中文)。

  • MIT License. See LICENSE. / 採用 MIT 授權,見 LICENSE

Available Tools

3 tools
get_verificationC

Fetch a previous verification result by trace_id.

ParametersJSON Schema
NameRequiredDescriptionDefault
trace_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

C2.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must disclose behavior. It only states it fetches a result, but does not indicate whether this is read-only, requires authentication, has rate limits, or what happens if the trace_id is unknown. The existence of an output schema partially covers return format, but the description adds minimal behavioral context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single short sentence, which is concise, but it is under-specified. It does not waste words, but it also does not earn its place with any extra guidance beyond the name. It is adequate but not informative.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's low complexity (one parameter) and the presence of an output schema, the description covers the basic action. However, it lacks any mention of usage context, error conditions, or relationship to sibling tools, making it incomplete for an agent to infer correct invocation in varied scenarios.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must explain the parameter. It mentions 'by trace_id' which implies the parameter identifies the verification, but offers no detail on format, origin, or constraints beyond the schema's basic string type. This is minimal added value.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a clear verb ('fetch') and resource ('verification result') plus the key parameter (trace_id). It implies the tool retrieves a previously created verification, which distinguishes it from sibling 'verify_source' that likely creates one, though it does not explicitly name the sibling.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this tool versus siblings, no context on prerequisites (e.g., must have a trace_id from a prior verification), and no exclusions. The description leaves the agent to infer usage solely from the tool name and parameter.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_known_identitiesA

List cached, independently-established project identities (official domains / orgs).

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the behavioral burden. It discloses that this is a non-mutating list operation and that results are cached and independently established, which helps set expectations about freshness and trustworthiness. It does not discuss staleness or caching semantics in depth, but for a zero-parameter listing tool the provided context is reasonably transparent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence that provides the key qualifiers ('cached', 'independently-established', 'official domains / orgs') without any filler. Every word adds meaning relevant to tool selection.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given that the tool has no parametersasi, an output schema exists, and the operation is a simple read-only list, the description provides sufficient context. It explains the source and nature of the identities while leaving return-value details to the output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so there is nothing for the description to document beyond what the schema already reflects. The baseline of 4 applies because no parameter semantics are needed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('List') and resource ('cached, independently-established project identities'), with an explicit parenthetical scope ('official domains / orgs'). This clearly distinguishes the tool from siblings like verify_source and get_verification, which focus on verification rather than enumeration.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage when you need already-known or cached identities rather than live verification, but it does not explicitly state when to prefer this tool over verify_source or get_verification. There is no exclusion guidance or alternative routing, so the usage context is inferred rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

verify_sourceA

Verify that url is an official / legitimate source for project.

Args: project: project / product name, e.g. "LM Studio". url: the download, installer, repository, model or data-source URL to check. description: what the URL is supposed to be, e.g. "Linux x64 AppImage installer". options: optional overrides: {"min_sources": 2, "allow_tier3": false, "history_days": 90}. Returns a dict with verdict (VERIFIED_TRUE | VERIFIED_FALSE | UNVERIFIABLE), confidence, reason (in the caller's language), evidence[], checks{}, identity{}, risk_signals[], cache_hits[], engine_notes[], trace_id.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYes
optionsNo
projectYes
descriptionNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the behavioral burden, and it provides substantial detail: the possible verdicts, confidence, reason language, evidence, checks, identity, risk signals, cache hits, engine notes, and trace ID. It also exposes meaningful behavior through the `options` overrides (`min_sources`, `allow_tier3`, `history_days`). It does not mention authorization, rate limits, or side effects, but the behavior is readable.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the single-sentence purpose, followed by a compact Args list and a compact Returns list. Every line adds information needed to call the tool, and there is no filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a verification tool with a rich return shape, the description covers the action, all parameters, and the output structure. The main gap is not guiding the agent relative to siblings, and the semantics of the `options` keys are only implicit, but nothing critical is missing for invoking the tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must define the parameters, and it does: `project` is exemplified, `url` is scoped to download/installer/repository/model/data URLs, `description` is explained with a concrete phrase, and `options` has literal defaults. This fully compensates for the schema's lack of descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence names a specific action and resource: verify that a `url` is an official/legitimate source for `project`. This is clearly distinct from the sibling tools `get_verification` and `list_known_identities`, which suggest retrieval and listing rather than on-demand verification.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the natural use case through 'Verify that ...' and the verdict return values, but it never states when to choose this over `get_verification` or `list_known_identities`, nor does it give exclusions or alternative routing. This is adequate but not explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 3 tool updatesv0.1.0
    • First observedget_verification
    • First observedlist_known_identities
    • First observedverify_source

TDQS

A3.8/5.0

Scored across 3 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: performing a verification, retrieving a past result by trace_id, and listing cached identities. There is no overlap or ambiguity between them.

Naming Consistency5/5

All tool names follow a consistent verb_noun snake_case pattern (verify_source, get_verification, list_known_identities), making the API predictable and easy to navigate.

Tool Count5/5

Three tools is well-scoped for a focused URL verification server: one primary action plus two supporting retrieval/listing utilities. Nothing feels missing or redundant.

Completeness4/5

The core verification workflow is fully covered, including result retrieval and identity discovery. Minor gaps exist, such as no way to list verification history or manage identities directly, but these are not blocking for the server's purpose.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    Verifies C2PA Content Credentials for local files or URLs and returns an LLM-ready verdict on trust, AI generation, and provenance.
    4
    5 npm
    1
    Apache 2.0
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI agents to check trustworthiness before recommending URLs, products, or organizations, with fail-closed pass/fail verdicts and attested-only recommendations.
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Enables agents to verify whether citations exist and match canonical records, and whether URLs resolve and contain expected content, with evidence-backed confirmed, contradicted, or unknown verdicts.
    2
    66 PyPI
    MIT