Skip to main content

Trust explained

ToolPin separates metadata completeness from evidence. The numeric score is a deterministic review score over registry metadata and the selected install target. The tier is evidence-gated: verified means automated evidence checks passed, not that a server is safe to run.

Score scale and computation

Every server starts at a base of 50. Signals add or subtract points, the running total is rounded, then clamped to 0–100. The score sorts attention and feeds local policy thresholds; it is not the same as the trust tier.

score = clamp(round(50 + serverSignals + Σ packageSignals + Σ remoteSignals), 0, 100)

Trust signals

The factors below are evaluated in src/trust.ts. Point values are exact.

Server-level signals

SignalConditionScore effectIssue / badge
Source repositoryrepositoryUrl present+8badge source repo
Source repository missingrepositoryUrl absent−8warning missing_repository
Namespaced namename contains /+6badge namespaced
No install targetno packages and no remotes−35critical no_install_target
Declares secretsrequiresSecrets is true−6info requires_secrets; badge requires secrets
Legacy transporttransports include sse−4info legacy_transport

Per-package signals (packageScore, summed for every package)

SignalConditionScore effectIssue / badge
Supported registry typetype in npm, pypi, nuget, cargo, oci, mcpb+5badge = type
Unknown registry typetype not in the supported set−8warning unknown_package_type
Strong registry typetype in oci, mcpb+4
Pinned versionversion present and not floating+5badge pinned version
Floating versionfloating version and type ≠ oci−6warning unpinned_package
OCI digest pinoci and identifier has @sha256:+8badge digest-pinned
OCI mutable tagoci and identifier lacks @sha256:−10critical mutable_oci_tag
MCPB hashmcpb and truthy fileSha256+8badge fileSha256
MCPB hash missingmcpb and no fileSha256−12critical missing_mcpb_hash

A version is treated as floating if it is latest or *, or contains any of ~ ^ x * (case-insensitive) — e.g. ^1.2.3, ~1.2, 1.x. OCI packages are exempt from the unpinned-version penalty; the digest pin is the stronger signal there.

Per-remote signals (remoteScore, summed for every remote)

SignalConditionScore effectIssue / badge
Remote declaredeach remote+6badge = remote type
HTTPS remoteparsed URL protocol is https:+6badge https remote
Insecure remoteparsed URL protocol is not https:−15critical insecure_remote
Invalid remote URLURL cannot be parsed−15critical invalid_remote_url
Streamable HTTPremote type is streamable-http+4

Evidence and tiers

TrustReport.evidence records automated evidence separately from badges:

Evidence codeStatusMeaning
package_pindeclared / failedPackage registry target declares an exact version, or an OCI target declares a digest pin. This is metadata, not byte verification.
digest_presentdeclared / failedOCI identifier includes @sha256:. This means the pin is present; oci_digest_verified records registry verification.
file_hash_presentdeclared / failedMCPB package declares fileSha256. This means the hash is present; mcpb_sha256_verified records byte hashing.
oci_digest_verifiedpassed / failed / unavailableToolPin resolved the OCI manifest digest through the registry API, or could not.
mcpb_sha256_verifiedpassed / failed / unavailableToolPin read MCPB bytes from a code-allowlisted HTTPS artifact host and recomputed SHA-256, or could not.
npm_integrity_verifiedpassed / failed / unavailableToolPin fetched the npm packument from registry.npmjs.org, required exact version dist.integrity, fetched a trusted npm tarball, and compared SHA-512 SRI.
lock_integritypassedNew lock entries include an integrity digest over the reviewed install plan, including entry timestamps.
tool_description_hashpassed / failed / unavailableLive package or remote tools/list descriptions were hashed, failed, or were skipped.
attestation_declareddeclaredAttestation metadata exists, but ToolPin has not cryptographically verified it.

Tiering is conservative. These are the same meanings surfaced by the TUI status labels:

  • verified / EVIDENCE: no critical issues, a pinned install target, and passed evidence with verifiedByToolPin: true, such as oci_digest_verified, mcpb_sha256_verified, npm_integrity_verified, or future verified attestations.
  • conditional / REVIEW: usable metadata or pinning exists, but artifact proof is incomplete, stale, unavailable, or only declared. Review the cap and evidence rows before installing.
  • unverified / UNVERIFIED: required pins or evidence are weak or failed, such as mutable OCI tags, missing MCPB hashes, failed optional evidence, or other non-blocking critical trust gaps.
  • blocked / BLOCKED: unsafe or uninstallable cases such as no install target, insecure remote URLs, invalid remote URLs, or failed required evidence checks.

Repository URL presence, registry source trust, capability-pinned, and self-declared attestations are useful review metadata. They do not make a server verified by themselves.

Why a score can be capped

ToolPin computes metadata completeness and pillar scores first, then caps the machine-readable overallScore when evidence is missing or a gate fires. A cap such as 69 is an evidence gate limit, not a percentile-like quality score. Trusted-source conditional entries are capped at 69% until ToolPin verifies artifact proof such as npm integrity, OCI digest, or MCPB hash evidence. Human CLI/TUI output uses the metadata/profile score for numeric differentiation and shows the evidence tier plus cap reason for verification status.

Common cap reasons:

Cap reasonMeaning
automated evidence incompleteMetadata and package pinning may look good, but ToolPin has not verified artifact bytes/provenance: an OCI @sha256:, MCPB fileSha256, or npm exact version may be declared without a successful oci_digest_verified, mcpb_sha256_verified, npm_integrity_verified, or future verified attestation. Declared pins and declared attestations alone do not count.
no verified provenanceThe entry is not from an official/Docker source with a repository URL, so provenance is not strong enough for a higher cap.
mutable_oci_tagThe OCI target uses a mutable tag instead of a digest.
missing_mcpb_hashThe MCPB target does not declare fileSha256.
veto: ...A blocked critical issue, such as no install target or an insecure/invalid remote URL, forces the score down.

CLI and TUI output include a cap line with a human-readable explanation when one of these caps applies.

Badges and findings that do not change the score

latest, capability-pinned, attestation badges, and the description-scan-advisory badge are recorded without a score delta. Advisory tool-description scan findings (from scanServerMetadata) are appended as issues for human review, not as score changes.

How severity maps to enforcement

Critical issues make toolpin verify report ok: false and can fail installs through policy. Warnings and info issues are surfaced for human review and policy decisions. minTrustScore in .toolpin/policy.json (an optional 0–100 number; there is no built-in default) enforces a numeric floor against the metadata/profile score, while minTrustTier enforces evidence-gated status.

Verification boundaries

ToolPin checks registry metadata, declared integrity pins, and lockfile drift. When --verify can reach a live server, it can hash normalized tool names and descriptions from tools/list and store that hash in the lockfile.

ToolPin does not:

  • Download OCI images and recompute the image digest.
  • Guarantee MCPB byte verification when the bundle is unavailable from a code-allowlisted HTTPS artifact host.
  • Prove publisher identity with sigstore or provenance attestations.
  • Detect prompt injection reliably.
  • Sandbox a server after it starts.

Use the score as an install-time gate, then combine it with code review, branch protection, runtime isolation, secret management, and client-side tool approval.