Skip to main content
Glama
README.md
# CRED-1: Open Domain Credibility Dataset

<p align="center">
  <img src="figures/cred1-domain-credibility-dataset-banner.jpg" alt="CRED-1 Domain Credibility Dataset Banner" width="100%">
</p>

[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.18769459.svg)](https://doi.org/10.5281/zenodo.18769459)
[![Publish](https://github.com/aloth/cred-1/actions/workflows/publish.yml/badge.svg)](https://github.com/aloth/cred-1/actions/workflows/publish.yml)
[![License: CC BY 4.0](https://img.shields.io/badge/License-CC%20BY%204.0-lightgrey.svg)](https://creativecommons.org/licenses/by/4.0/)
[![npm version](https://img.shields.io/npm/v/@aloth/cred1.svg)](https://www.npmjs.com/package/@aloth/cred1)
[![npm downloads](https://img.shields.io/npm/dm/@aloth/cred1.svg)](https://www.npmjs.com/package/@aloth/cred1)
[![CalVer](https://img.shields.io/badge/calver-YYYY.M.D-blue.svg)](https://calver.org/)
[![Report Missing Domain](https://img.shields.io/badge/Report-Missing%20Domain-orange)](https://github.com/aloth/cred-1/issues/new?template=domain-report.yml)

**CRED-1** is an open, reproducible domain-level credibility dataset combining multiple openly-licensed source lists with computed enrichment signals. It provides credibility scores for **2,600+ domains** (exact count in the [latest release](https://github.com/aloth/cred-1/releases/latest)) known to publish mis/disinformation, conspiracy theories, or other unreliable content. Community members can [report missing domains](https://github.com/aloth/cred-1/issues/new?template=domain-report.yml) for inclusion.

> ๐ŸŽ“ **Presented at ACM WebSci 2026 (Braunschweig).** Landing page: [aloth.github.io/agentic-ai-information-integrity/cred-1](https://aloth.github.io/agentic-ai-information-integrity/cred-1/).

> ๐Ÿค– **MCP-ready** โ€” query domain credibility directly from Claude Desktop, Cursor & Windsurf, or any MCP-compatible agent. [Jump to setup โ†“](#mcp-server-claude-desktop--cursor--windsurf)

> **Paper:** A. Loth, M. Kappes, and M.-O. Pahl, "CRED-1: An Open Multi-Signal Domain Credibility Dataset for Automated Pre-Bunking of Online Misinformation," *Preprint*, 2026. [doi:10.2139/ssrn.6448466](https://doi.org/10.2139/ssrn.6448466)

---

## Install

```bash
# CLI (global)
npm install -g @aloth/cred1

# Library (project dependency)
npm install @aloth/cred1

# Or try without installing
npx @aloth/cred1 check infowars.com
```

## CLI Usage

```bash
# Single domain lookup
cred1 check infowars.com
# ๐Ÿ”ด  infowars.com
#    Score:    0.073 / 1.000
#    Category: conspiracy
#    Level:    low
#    Sources:  2

# Domain not in dataset
cred1 check nytimes.com
# โšช  nytimes.com
#    Not found in CRED-1 dataset โ€” treat as unknown/neutral

# Batch processing (stdin)
echo -e "rt.com\ninfowars.com\nnytimes.com" | cred1 batch

# JSON output
cred1 check breitbart.com --json

# Search
cred1 search "news"
cred1 search "\.ru$"

# Statistics
cred1 stats
cred1 categories
```

Domain normalization is automatic โ€” `https://www.infowars.com/politics/` resolves to `infowars.com`.

## MCP Server (Claude Desktop / Cursor / Windsurf)

CRED-1 ships an [MCP](https://modelcontextprotocol.io/) server so AI assistants can check domain credibility directly.

### Tools exposed

| Tool | Description |
|------|-------------|
| `check_domain` | Check a single domain (score, category, level, metadata) |
| `batch_check` | Check up to 100 domains at once |
| `search_domains` | Search domains by substring or regex pattern |
| `get_stats` | Dataset statistics (total, per-category counts, version) |
| `get_categories` | Category taxonomy with descriptions and score ranges |

### Claude Desktop

Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "cred1": {
      "command": "npx",
      "args": ["-y", "@aloth/cred1", "--mcp"]
    }
  }
}
```

> **Note:** `--mcp` is handled by the CLI wrapper โ€” or run the dedicated binary directly.

Alternatively, if the package is installed globally:

```json
{
  "mcpServers": {
    "cred1": {
      "command": "cred1-mcp"
    }
  }
}
```

### Cursor

Add to `.cursor/mcp.json` (project) or `~/.cursor/mcp.json` (global):

```json
{
  "mcpServers": {
    "cred1": {
      "command": "npx",
      "args": ["-y", "@aloth/cred1", "--mcp"]
    }
  }
}
```

### Windsurf

Add to `~/.codeium/windsurf/mcp_config.json`:

```json
{
  "mcpServers": {
    "cred1": {
      "command": "npx",
      "args": ["-y", "@aloth/cred1", "--mcp"]
    }
  }
}
```

### OpenClaw / any MCP-compatible host

```json
{
  "command": "cred1-mcp",
  "transport": "stdio"
}
```

### Pinning a version

With `npx -y @aloth/cred1`, npx checks npm for a newer version each time the host starts the server and installs it, and a new version is published every week. A host restart can therefore run a release you have not reviewed. To decide when to update, pin the version in the config:

```json
{
  "mcpServers": {
    "cred1": {
      "command": "npx",
      "args": ["-y", "@aloth/cred1@2026.10.27", "--mcp"]
    }
  }
}
```

Or install a fixed version globally and point the host at the `cred1-mcp` binary as shown above:

```bash
npm install -g @aloth/cred1@2026.10.27
```

Replace `2026.10.27` with the version you reviewed; `npm view @aloth/cred1 version` prints the latest one.

Most weekly releases only refresh the bundled dataset (`data/cred1_compact.json`), but every release is built from the current `main` branch, so code changes ship the same way. To see what changed between two versions, compare their tags, for example [`v2026-10-20...v2026-10-27`](https://github.com/aloth/cred-1/compare/v2026-10-20...v2026-10-27). The server reads the dataset from the installed package and makes no network requests. Since `2026.6.14`, releases are published from GitHub Actions with [npm provenance](https://docs.npmjs.com/generating-provenance-statements), which `npm audit signatures` verifies.

---

## Library Usage

```typescript
import { checkDomain, searchDomains, getStats } from '@aloth/cred1';

// Single lookup
const result = checkDomain('infowars.com');
// { domain: 'infowars.com', score: 0.073, category: 'conspiracy', level: 'low', sources: 2, domainAge: 27.3, trancoRank: 15889 }

// Not found โ†’ null
const unknown = checkDomain('nytimes.com'); // null

// Search by pattern (substring or regex)
const russian = searchDomains('\\.ru$');

// Dataset statistics
const stats = getStats();
// { totalDomains: 2673, categories: { unreliable: 2001, fake: 233, ... }, version: '1.0.0' }
```

## Traffic-Light Scoring

| Level   | Score     | Emoji | Meaning                          |
|---------|-----------|-------|----------------------------------|
| low     | โ‰ค 0.20   | ๐Ÿ”ด    | High credibility risk            |
| mixed   | 0.21โ€“0.50 | ๐ŸŸก    | Unreliable or mixed signals      |
| ok      | > 0.50   | ๐ŸŸข    | Generally considered reliable    |
| neutral | not found | โšช    | Unknown โ€” absence โ‰  trustworthy  |

## Key Features

- **2,674 domains** with credibility scores (0.0โ€“1.0)
- **Dual-mode** โ€” works as CLI tool and JavaScript library
- **Fully reproducible** โ€” Python pipeline rebuilds the dataset from scratch
- **Multi-signal scoring** combining source labels, domain age, web popularity, fact-check frequency, and threat intelligence
- **Privacy-preserving** โ€” designed for on-device client-side deployment (no server calls needed)
- **Two openly-licensed sources** โ€” no proprietary data dependencies
- **Domain normalization** โ€” handles www., protocols, paths automatically

## Dataset Schema

### Compact Format (`cred1_compact.json`)

```json
{
  "infowars.com": { "c": "c", "s": 0.073, "n": 2, "d": "1999-10-04", "r": 15889 }
}
```

| Field | Description |
|-------|-------------|
| `c`   | Category code: `f`=fake, `u`=unreliable, `m`=mixed, `c`=conspiracy, `s`=satire, `r`=rumor. |
| `s`   | Credibility score (0.0โ€“1.0, lower = less credible) |
| `n`   | Number of independent source lists flagging this domain |
| `d`   | Domain registration date (optional) |
| `r`   | Tranco Top-1M rank (optional โ€” lower rank = more popular) |

### Full Format (`cred1_current.json`)

```json
{
  "infowars.com": {
    "category": "fake",
    "credibility_score": 0.14,
    "domain_age_years": 26.4,
    "domain_registered": "1999-10-04T04:00:00Z",
    "iffy_factual": "VL",
    "iffy_bias": "FN",
    "iffy_score": 0.1,
    "factcheck_claims": 52,
    "safe_browsing_flagged": false,
    "score_age": 0.2,
    "score_cat": 0.05,
    "score_factcheck": 0.0,
    "score_iffy": 0.1,
    "score_safebrowsing": 0.05,
    "score_tranco": 0.1,
    "sources": 2,
    "tranco_rank": 4382
  }
}
```

See [CODEBOOK.md](CODEBOOK.md) for full field documentation.

### What the score is, and what it is not

The credibility score is a **domain-level** signal, not an item-level verdict. It says how a source has been rated by public source-rating initiatives; it does not say whether any individual article is true. Research that uses it as a veracity label is therefore working with a **provenance-implied rather than item-verified** signal: material drawn from domains scoring below 0.25 can be labelled low-credibility, material from established outlets legitimate, but no single item has been fact-checked. Outlet reputation is a good but imperfect proxy, and that bound should be carried into any reuse.

## Rebuilding the Dataset

```bash
cd pipeline/
python3 build_dataset.py              # Full pipeline
python3 build_dataset.py --step fetch # Download raw data only
python3 build_dataset.py --step merge # Parse + merge (requires prior fetch)
python3 enrich_dataset.py             # Add enrichment signals (API keys required)
```

## Versioning

CRED-1 uses **calendar versioning** (CalVer) across all distribution channels:

| Channel | Format | Example |
|---------|--------|---------|
| GitHub Release | `v2026-06-13` | Tag + Zenodo archive |
| npm package | `2026.6.13` | Same date, dot-separated (valid semver) |

A new version is released **weekly** with rescored domains. The npm package updates automatically with each GitHub release โ€” no separate version scheme needed.

To pin a specific dataset version:
```bash
npm install @aloth/cred1@2026.6.13
```

## Production Integrations

- **[Trackless Links](https://github.com/aloth/trackless-links)** โ€” Safari extension for iOS and macOS that checks links locally against CRED-1 (reviewed in Mac & i 4/2026)
- **[RogueGPT](https://github.com/aloth/RogueGPT)** โ€” Uses CRED-1 to identify low-credibility source domains for controlled fake-news stimulus generation
- **[HuggingFace](https://huggingface.co/datasets/xlth/CRED-1)** โ€” Dataset mirror for ML pipelines

## Contributing

Know a domain that should be in the dataset? [Report a missing domain](https://github.com/aloth/cred-1/issues/new?template=domain-report.yml) with evidence.

We accept community-reported domains that meet at least one of these criteria:

- Listed by [Media Bias/Fact Check](https://mediabiasfactcheck.com/) (MBFC)
- Flagged by an [IFCN](https://ifcncodeofprinciples.poynter.org/)-certified fact-checker
- Subject to press council or regulatory action
- Documented in Wikipedia with credibility concerns
- Referenced in published academic research

Accepted domains are added to the pipeline and appear in the next weekly dataset release.

## Citation

If you use CRED-1 in your work, please cite **both** the paper and the dataset version you used. The paper describes the method; the Zenodo record pins the exact data, which is what makes your results reproducible.

**Paper:**

```bibtex
@misc{loth2026cred1,
  author       = {Loth, Alexander and Kappes, Martin and Pahl, Marc-Oliver},
  title        = {{CRED-1}: An Open Multi-Signal Domain Credibility Dataset for Automated Pre-Bunking of Online Misinformation},
  year         = {2026},
  howpublished = {Preprint},
  doi          = {10.2139/ssrn.6448466},
  url          = {https://ssrn.com/abstract=6448466},
  urldate      = {2026-08-25}
}
```

**Dataset:**

```bibtex
@dataset{loth2026cred1data,
  author       = {Loth, Alexander},
  title        = {{CRED-1}: An Open Multi-Signal Domain Credibility Dataset},
  year         = {2026},
  publisher    = {Zenodo},
  version      = {v2026-03-17},
  doi          = {10.5281/zenodo.18769459},
  url          = {https://doi.org/10.5281/zenodo.18769459}
}
```

The DOI above always resolves to the latest release. To cite a specific weekly snapshot, use the version DOI shown on that release's Zenodo page.

## Related Projects

CRED-1 is one strand of a wider research program on generated disinformation. The domain scores are used to select low-credibility sources for stimulus generation in RogueGPT:

| Project | Description |
|:---|:---|
| [JudgeGPT](https://github.com/aloth/JudgeGPT) | Empirical platform for evaluating AI-generated news authenticity |
| [RogueGPT](https://github.com/aloth/RogueGPT) | Controlled stimulus generator; draws fake-news sources from CRED-1 scores |
| [verification-crisis](https://github.com/aloth/verification-crisis) | Expert survey on GenAI disinformation threats and countermeasures |
| [Origin Lens](https://github.com/aloth/origin-lens) | iOS app for C2PA content credentials and EXIF verification |
| [provenance-linkage](https://github.com/aloth/provenance-linkage) | Reproducibility bundle for a benchmark audit of AI-text detection |

### Companion data deposits

CRED-1 is archived alongside three companion datasets, which are versioned together so that they can be cited as one coherent set:

| Deposit | Concept DOI | Current version |
|:---|:---|:---|
| RogueGPT Stimulus Corpus | [10.5281/zenodo.18703137](https://doi.org/10.5281/zenodo.18703137) | [22225536](https://doi.org/10.5281/zenodo.22225536) (v1.2.0) |
| JudgeGPT Human Perception Data | [10.5281/zenodo.18703384](https://doi.org/10.5281/zenodo.18703384) | [22226580](https://doi.org/10.5281/zenodo.22226580) (v1.2.0) |
| Expert Survey | [10.5281/zenodo.18703600](https://doi.org/10.5281/zenodo.18703600) | [22226924](https://doi.org/10.5281/zenodo.22226924) (v2.1.0) |

## Related Publications

- **Interrupting the Chain: Human Perception of AI-Generated Disinformation Through a Kill Chain Lens** (INFORMATIK 2026, LNI). Positions domain-level credibility as a Delivery-stage signal. [arXiv:2608.21389](https://arxiv.org/abs/2608.21389)
- **Blessing or Curse? A Survey on the Impact of Generative AI on Fake News** (2024). [arXiv:2404.03021](https://arxiv.org/abs/2404.03021)

## License

- **Dataset:** [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/). Copyright 2025-2026 Alexander Loth.
- **Code & CLI:** [MIT](LICENSE)

The dataset is an aggregation of domain-level ratings from public source-rating initiatives. The aggregation, scoring and documentation are this project's own work and are released under CC BY 4.0; the underlying ratings remain attributable to their respective initiatives, which are named per record and listed in [ATTRIBUTION.md](ATTRIBUTION.md). No access restriction applies to the dataset.

## Author

Alexander Loth โ€” [alexloth.com](https://alexloth.com) ยท [@xlth](https://x.com/xlth) ยท [ORCID](https://orcid.org/0009-0003-9327-6865)

TDQS

A4/5.0

Scored across 5 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: single lookup, bulk lookup, pattern search, dataset-level stats, and category metadata. There is no realistic scenario where an agent would confuse check_domain with search_domains or get_stats, and batch_check is explicitly distinguished by its multi-domain input and result array.

Naming Consistency4/5

Four tools follow a clean verb_noun pattern (check_domain, search_domains, get_stats, get_categories). batch_check deviates slightly by putting the noun first, but it remains readable and the intent is obvious, so this is a minor deviation rather than an inconsistency problem.

Tool Count5/5

Five tools is a tight, well-scoped surface for a domain credibility dataset: one tool per natural operation (read one, read many, search, stats, taxonomy). Nothing appears redundant or missing at the count level.

Completeness5/5

For a read-only dataset server, the surface covers all expected workflows: single lookup, bulk lookup with not_found handling, discovery via substring/regex search, aggregate statistics, and category taxonomy. There are no dead ends an agent would hit in normal use.

Maintenance

ActivityActive
ResponsivenessSlow