Skill: chuxo/epstein (version 1.1.0)

--- name: epstein description: > Search 44,886+ DOJ-released Jeffrey Epstein documents (Jan 2026 release). Free, no payment required. Search by name, topic, location, or keyword across the full DugganUSA index of declassified Epstein files. Returns document previews, people mentioned, locations, aircraft, evidence types, and source references. metadata: author: project-einstein version: "1.1.0" clawdbot: emoji: "📂" homepage: "https://emc2ai.io" requires: bins: ["node", "curl"] --- # Epstein Files Search — Free DOJ Document Search Search **44,886+ declassified Jeffrey Epstein documents** released by the U.S. Department of Justice on January 30, 2026. Powered by the [DugganUSA](https://analytics.dugganusa.com) public index. **100% free. No API keys. No accounts. No payment.** ## Quick Start ```bash # Search by name node scripts/epstein.mjs search --query "Ghislaine Maxwell" --limit 10 # Search by topic node scripts/epstein.mjs search --query "flight logs" --limit 20 # Search by location node scripts/epstein.mjs search --query "Little St James" # Get index statistics node scripts/epstein.mjs stats ``` ## Commands ### `search` — Search Epstein Documents Search across all 44,886+ indexed documents by keyword, name, topic, or location. ```bash node scripts/epstein.mjs search --query "SEARCH TERMS" [--limit N] ``` | Flag | Description | Default | |------|-------------|---------| | `--query <terms>` | Search query (required) | — | | `--limit <N>` | Number of results (1-500) | `10` | **Examples:** ```bash # Search for a specific person node scripts/epstein.mjs search --query "Prince Andrew" # Search for a topic node scripts/epstein.mjs search --query "financial transactions" # Search for locations node scripts/epstein.mjs search --query "New York mansion" # Get more results node scripts/epstein.mjs search --query "flight logs" --limit 50 # Search for evidence types node scripts/epstein.mjs search --query "phone records" ``` ### `stats` — Index Statistics Get the current state of the document index — total documents, database size, and last update time. ```bash node scripts/epstein.mjs stats ``` ## Output Format Search results are returned as JSON to stdout (for easy piping and parsing). Status messages and **Quick Links** (direct PDF URLs) go to stderr for easy viewing. ### Search Result Shape ```json { "query": "flight logs", "totalHits": 1523, "hits": [ { "id": "doc-abc123", "efta_id": "EFTA-00001234", "content_preview": "Excerpt from the document...", "doc_type": "legal_document", "dataset": "epstein_files", "pages": 3, "people": ["Person A", "Person B"], "locations": ["New York", "Palm Beach"], "aircraft": ["N908JE"], "evidence_types": ["financial_record"], "source": "DOJ Release Jan 2026", "indexed_at": "2026-01-31T...", "doj_url": "https://www.justice.gov/epstein/files/DataSet%209/EFTA-00001234.pdf", "doj_listing_url": "https://www.justice.gov/epstein/doj-disclosures/data-set-9-files" } ] } ``` **New in v1.1.0:** Each result now includes `doj_url` (direct PDF link) and `doj_listing_url` (dataset page). The CLI also displays Quick Links in stderr output: ``` --- Quick Links --- 1. EFTA-00001234: https://www.justice.gov/epstein/files/DataSet%209/EFTA-00001234.pdf 2. EFTA-00001235: https://www.justice.gov/epstein/files/DataSet%209/EFTA-00001235.pdf ``` ### Stats Shape ```json { "totalDocuments": 44886, "databaseSize": "2.1 GB", "lastUpdate": "2026-01-31T...", "isIndexing": false } ``` ## Data Source All documents come from the **U.S. Department of Justice** release of Jeffrey Epstein-related records on January 30, 2026. The documents are indexed and searchable via the [DugganUSA](https://analytics.dugganusa.com) public API. - **Source**: [DOJ Epstein Records](https://www.justice.gov/epstein) - **Index**: [DugganUSA Analytics](https://analytics.dugganusa.com) - **Coverage**: 44,886+ document files (3+ million pages) - **Content**: Court filings, depositions, flight logs, financial records, communications, evidence inventories, and more ## Piping & Integration Results go to stdout as JSON, making it easy to pipe into other tools: ```bash # Pipe to jq for filtering node scripts/epstein.mjs search --query "Maxwell" --limit 100 | jq '.hits[] | .people' # Save results to file node scripts/epstein.mjs search --query "flight logs" --limit 500 > flight-logs.json # Count total hits node scripts/epstein.mjs search --query "Palm Beach" | jq '.totalHits' # Extract all mentioned people node scripts/epstein.mjs search --query "2005" --limit 100 | jq '[.hits[].people[]?] | unique' ``` ## Troubleshooting **"Cannot reach API"** Check your internet connection. The DugganUSA API may have temporary downtime. **"No results found"** Try broader search terms. The search is keyword-based — use names, locations, or document types rather than full sentences. **Slow responses** The API typically responds in 100-900ms. Larger result sets (limit > 100) may take slightly longer. ## References - [DOJ Epstein Records](https://www.justice.gov/epstein) — Official DOJ release page - [DugganUSA API](https://analytics.dugganusa.com) — Search index provider - [Project Einstein](https://emc2ai.io) — AI agent with built-in Epstein files search

path: package.json
content: name: epstein-files-skill
version: 1.1.0
type: module
private: yes
description: Search 44,886+ DOJ-released Jeffrey Epstein documents with direct PDF links (free, no payment required)

path: scripts/epstein.mjs
content: #!/usr/bin/env node

/**
 * Epstein Files Search — OpenClaw Skill
 *
 * Search 44,886+ DOJ-released Jeffrey Epstein documents via the
 * DugganUSA public API. Free, no payment or API keys required.
 *
 * Usage:
 *   node scripts/epstein.mjs search --query "search terms" [--limit N]
 *   node scripts/epstein.mjs stats
 *
 * Examples:
 *   node scripts/epstein.mjs search --query "Ghislaine Maxwell" --limit 10
 *   node scripts/epstein.mjs search --query "flight logs" --limit 50
 *   node scripts/epstein.mjs stats
 */

const API_BASE = 'https://analytics.dugganusa.com/api/v1';
const TIMEOUT = 15_000;

// ---------------------------------------------------------------------------
// Argument parsing
// ---------------------------------------------------------------------------

function parseArgs(argv) {
  const args = { _: [] };
  let i = 2; // skip node and script path
  while (i < argv.length) {
    const arg = argv[i];
    if (arg.startsWith('--')) {
      const key = arg.slice(2);
      const next = argv[i + 1];
      if (next && !next.startsWith('--')) {
        args[key] = next;
        i += 2;
      } else {
        args[key] = true;
        i += 1;
      }
    } else {
      args._.push(arg);
      i += 1;
    }
  }
  return args;
}

// ---------------------------------------------------------------------------
// Search command
// ---------------------------------------------------------------------------

async function search(query, limit) {
  const apiUrl = `${API_BASE}/search?q=${encodeURIComponent(query)}&indexes=epstein_files`;
  process.stderr.write(`Searching Epstein files for: "${query}" (limit: ${limit})\n`);

  const res = await fetch(apiUrl, { signal: AbortSignal.timeout(TIMEOUT) });
  if (!res.ok) throw new Error(`API returned ${res.status}: ${res.statusText}`);

  const body = await res.json();
  const hits = (body?.data?.hits || []).slice(0, limit);
  const result = {
    query: body?.data?.query || query,
    totalHits: body?.data?.totalHits ?? 0,
    hits,
  };

  console.log(JSON.stringify(result, null, 2));

  // Print human-readable summary to stderr
  process.stderr.write(`\nFound ${result.totalHits} documents (showing ${hits.length})\n`);
  if (hits.length > 0) {
    process.stderr.write('\n--- Quick Links ---\n');
    hits.forEach((doc, i) => {
      const id = doc.efta_id || doc.id;
      const url = doc.doj_url;
      if (url) {
        process.stderr.write(`${i + 1}. ${id}: ${url}\n`);
      }
    });
  }
}

// ---------------------------------------------------------------------------
// Stats command
// ---------------------------------------------------------------------------

async function stats() {
  process.stderr.write('Fetching index statistics...\n');

  const res = await fetch(`${API_BASE}/search/stats`, {
    signal: AbortSignal.timeout(TIMEOUT),
  });
  if (!res.ok) throw new Error(`API returned ${res.status}: ${res.statusText}`);

  const body = await res.json();
  const epsteinIndex = body?.data?.indexes?.find((i) => i.name === 'epstein_files');

  const result = {
    totalDocuments: epsteinIndex?.numberOfDocuments ?? 0,
    databaseSize: body?.data?.databaseSize ?? 'unknown',
    lastUpdate: body?.data?.lastUpdate ?? 'unknown',
    isIndexing: epsteinIndex?.isIndexing ?? false,
  };

  console.log(JSON.stringify(result, null, 2));
  process.stderr.write(
    `\nIndex: ${result.totalDocuments.toLocaleString()} documents, ` +
      `${result.databaseSize}, indexing: ${result.isIndexing}\n`
  );
}

// ---------------------------------------------------------------------------
// Main
// ---------------------------------------------------------------------------

async function main() {
  const args = parseArgs(process.argv);
  const command = args._[0];

  if (!command || command === 'help' || command === '--help' || command === '-h') {
    process.stderr.write(`
Epstein Files Search — OpenClaw Skill

Search 44,886+ DOJ-released Jeffrey Epstein documents (Jan 2026).
Free — no API keys, no payment, no accounts required.

Usage: node scripts/epstein.mjs <command> [options]

Commands:
  search    Search documents by keyword, name, topic, or location
  stats     Show index statistics (document count, size, status)

Options:
  --query <terms>   Search query (required for search command)
  --limit <N>       Number of results, 1-500 (default: 10)

Examples:
  node scripts/epstein.mjs search --query "Ghislaine Maxwell" --limit 10
  node scripts/epstein.mjs search --query "flight logs" --limit 50
  node scripts/epstein.mjs search --query "Little St James"
  node scripts/epstein.mjs stats
`);
    process.exit(0);
  }

  if (command === 'stats') {
    try {
      await stats();
    } catch (err) {
      process.stderr.write(`\nError: ${err.message}\n`);
      process.stderr.write('The DugganUSA API may be temporarily unavailable.\n');
      process.exit(1);
    }
    process.exit(0);
  }

  if (command === 'search') {
    const query = args.query || args.q || args._.slice(1).join(' ');
    if (!query) {
      process.stderr.write('Error: --query <search terms> is required\n');
      process.stderr.write(
        'Example: node scripts/epstein.mjs search --query "flight logs"\n'
      );
      process.exit(1);
    }
    const limit = Math.min(Math.max(parseInt(args.limit || '10', 10), 1), 500);

    try {
      await search(query, limit);
    } catch (err) {
      process.stderr.write(`\nError: ${err.message}\n`);
      process.stderr.write('The DugganUSA API may be temporarily unavailable.\n');
      process.exit(1);
    }
    process.exit(0);
  }

  process.stderr.write(`Unknown command: ${command}\n`);
  process.stderr.write('Run: node scripts/epstein.mjs help\n');
  process.exit(1);
}

main();


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: clean (LOW)