{
  "markdown": "# epstein\n\nFull-text search over the documents the House Oversight Committee has published\nfor its Jeffrey Epstein investigation — transcribed interviews, subpoenas and\nletters — plus (phase 2) a structured search over Epstein's own pilot flight\nlogbook. **Fleet #1480, phases 1-2.**\n\nPart of [Pipeworx](https://pipeworx.io) — an MCP gateway connecting AI agents to 1558+ live data sources.\n\n## Tools\n\n| Tool | Answers |\n|---|---|\n| `epstein_search_documents` | Where a phrase appears in the record, as a page-level citation |\n| `epstein_list_documents` | What the corpus contains, and what is not searchable |\n| `epstein_get_document` | The full text of one document, a page at a time |\n| `epstein_flight_log_search` | Who is logged on a given tail number, route or date range, as the pilot wrote it |\n\nTools are prefixed because `search_documents` is already taken by\n`federal-register` and `riksdagen-se`; a colliding tool ships unreachable while\nthe error advertises a namespaced name that does not resolve.\n\n## Phase 2: the flight logbook\n\n`epstein_flight_log_search` reads Government Exhibit 662-RR — Epstein's own\npilot flight logbook (1991-2005), admitted into evidence and unsealed in *USA\nv. Ghislaine Maxwell*, 20-cr-330 (S.D.N.Y.), hosted keylessly at a stable\nDocumentCloud asset URL. Phase 1's original release note said no flight logs\nexisted anywhere in the House Oversight corpus — true, but that was never the\nonly public source. This exhibit is a fixed, closed 118-page historical\ndocument, not a live feed, so ingest is a one-time transcription rather than a\nper-request proxy call.\n\n**397 of an estimated 3,000+ logged legs are ingested — 23 of the 118 pages**\n(fleet #1880 added pages 4-13 to the original 10-page seed, which was chosen to\nspan the full 1991-2005 range; fleet #1881 added pages 14-16). Machine OCR of\nthis handwritten logbook is unusable (the exhibit's own bundled OCR text layer\nis illegible line noise, verified before building this); every ingested row is\na direct visual transcription of the page image. `epstein_flight_log_search`\nwith no filters returns the exact pages covered so an absence never reads as\n\"did not fly\" — it may simply mean the page is not yet transcribed. Completing\nthe remaining 95 pages is follow-on work, not a blocker to shipping this\nslice.\n\n**Confidence convention on the transcription itself (fleet #1880):**\n`passengers_raw` is verbatim per row — the same person's name is NOT\nnormalized to one spelling across rows even where it clearly varies\n(\"Krestena\" / \"Kristena\" / \"Christina\" all occur for what is plausibly one\nperson). A token read with real but not total confidence carries a trailing\n`[?]` inside the word it qualifies (`\"Arthur Hallering[?]\"`); a token that\ncould not be read at all is `[illegible]`. Neither is a guess standing in for\na fact. A pilot's own struck-through self-correction is omitted rather than\nmarked `[redacted]` — that marker is reserved for a black-out on the original\nexhibit page.\n\n**Design decision C is held exactly: passenger entries are never resolved.**\n\"JE\", \"GM\", \"SK\" and similar initials are stored and returned *exactly as the\npilot wrote them*, never expanded to a full identity — even where that\nidentity is publicly reported elsewhere. A black-out on the original page is\nstored as the literal marker `[redacted]`; a word the transcriber could not\nread with confidence is stored as `[illegible]`. Neither is a guess standing\nin for a fact.\n\nEvery row carries its own provenance: exhibit title, the page number as\nprinted on the page itself, the DocumentCloud `source_url`, and the sha256 of\nthe source PDF, so a caller never has to trust that two rows came from the\nsame file.\n\n## What this is, and what it is not\n\nThis is **one committee's published PDFs**. It is not \"the Epstein files\", and\nevery response says so rather than letting the name imply completeness.\n\n- We already had the **committee layer**: `search_committee_documents` returns\n  the releases, subpoena announcements and staff memoranda in which Oversight\n  *talks about* this investigation. This pack holds what those releases link to.\n- **Court filings and dockets are not here** — those are `court-listener`, and\n  should be joined to rather than duplicated.\n- **The estate tranche is absent.** The 2025-11-12 release *\"Oversight Committee\n  Releases Additional Epstein Estate Documents\"* links a Google Drive folder that\n  now returns 404. Those documents are not retrievable from this source. Do not\n  add a Drive scraper to chase it; the folder is gone, not hidden.\n\nCorpus as built: **31 documents, 505 pages, ~800,000 characters**, including the\nBarr (129p), Tova Noel (135p) and Bondi (111p) transcribed interviews.\n\n## Every result is a citation\n\nA match returns the document title, the **page number** and the committee's own\nURL, because the only useful form of this material is one a reader can check:\n\n```\n\"2025.08.05 Subpoena Cover Letters, page 33 — https://oversight.house.gov/...\"\n```\n\nPage-level storage is a requirement, not a convenience — later phases\n(person profiles, connections) are built on this table, and design decision B on\nthe task says an edge must *be* its citation.\n\n## What this phase deliberately does not do\n\nNo entity pages, no relationship scores, no \"associate of\", no inferred\nconnections. A name appearing in a document is a fact about the document;\nanything beyond that is a claim, and for people never charged with anything a\nloosely derived edge is defamation-shaped. Phases 3–5 (emails, person\nprofiles, connections) are a layer over phases 1-2 and carry their own\nrules — in particular, people come from **unsealing orders**, never from name\nextraction over the text, because an unsealed name and a redaction failure look\nidentical on the page. Phase 2's passenger entries are exempt from that rule by\ndesign decision C: they are never resolved to an identity at all, so the\nredaction-failure risk that motivates decision A does not apply the same way —\nnothing is asserted as a person, an initial is returned as an initial.\n\n## Four documents cannot be searched, and say so\n\n4 of the 31 are scans with no text layer (two subpoena schedules, two letters).\nThey appear in `epstein_list_documents` with `searchable: false`, and\n`epstein_get_document` refuses them by name with a link to the original. Storing\nthem as empty text would make a document that exists match nothing — which reads\nas \"not in the corpus\" rather than \"not machine-readable\".\n\n## Data sources\n\n- House Committee on Oversight and Government Reform, release pages and the PDFs\n  they link under `oversight.house.gov/wp-content/uploads/YYYY/MM/`. Free, no\n  credential. There is no bulk endpoint: the release pages **are** the index, so\n  the ingest walks the committee release pages themselves.\n- `.github/workflows/epstein-refresh.yml` re-harvests weekly. The committee adds\n  to this investigation on its own schedule — three transcribed interviews\n  arrived in three separate releases.\n- Government Exhibit 662-RR, `USA v. Ghislaine Maxwell`, 20-cr-330 (S.D.N.Y.) —\n  a court trial exhibit, admitted into evidence and unsealed, hosted keylessly\n  at a stable DocumentCloud asset URL. A fixed, closed historical document, not\n  a live feed, ingested once as a one-time transcription (migration\n  `186_epstein_flight_logs.sql`) rather than proxied per request.\n\n**A truncated PDF downloads as a success.** Measured while building this: the\nBondi transcript came back 131,072 bytes against a declared 392,928, `curl`\nexited 0, and `file(1)` still called it a valid PDF — it would have been indexed\nas a third of a transcript with nothing reporting a problem. The ingest checks\nContent-Length and the `%%EOF` trailer on every fetch, and retries.\n\n## Fetching the exhibit: the User-Agent rule is backwards here\n\n`s3.documentcloud.org` answers a **plain bot User-Agent with 200** and a **full\nChrome User-Agent with 403**. Measured three ways on the same URL in the same\nminute: `pipeworx/1.0` → 200, a normal Chrome UA → 403, no UA at all → 200. The\n`www.documentcloud.org` page and its API refuse the browser UA too.\n\nThis is the opposite of the usual rule — `war.gov`, `dol.gov` and `gao.gov` all\nneed full browser headers to answer at all. Presumably a browser UA arriving\nfrom a datacenter IP with no browser fingerprint scores worse than an honest\ncrawler does.\n\nIt matters because the 403 is a **4.7 KB Cloudflare block page**, not a network\nerror: a fetch that does not check its result records a \"downloaded\" 4.7 KB PDF\nand carries on. Send a plain honest User-Agent, and check `Content-Length` and\nthe `%%EOF` trailer regardless.\n\n## Quick Start\n\nAdd to your MCP client (Claude Desktop, Cursor, Windsurf, etc.):\n\n```json\n{\n  \"mcpServers\": {\n    \"epstein\": {\n      \"url\": \"https://gateway.pipeworx.io/epstein/mcp\"\n    }\n  }\n}\n```\n\n### What this endpoint actually serves\n\n`tools/list` at `https://gateway.pipeworx.io/epstein/mcp` returns the tools in the table\nabove **plus the shared Pipeworx meta-tools** — `ask_pipeworx`,\n`discover_tools`, `search_within`, `remember`/`recall` and the rest of the\ngateway-wide set. So the tool count you see is larger than this table: a\nsingle-pack endpoint currently lists roughly 30 shared tools alongside the\npack's own. The connection's `initialize` response states its exact scope, and\nis the authoritative answer for a given day.\n\nThis is deliberate, not multiplexing by accident. The meta-tools are what let a\nscoped connection answer a question this pack does not cover — via\n`ask_pipeworx`, which routes across the whole catalog — without you adding a\nsecond MCP server. There is currently no way to mount a pack endpoint without\nthem; if the extra schemas cost you more context than the routing is worth,\nconnect to the full gateway once rather than to several pack endpoints.\n\nOr connect to the full Pipeworx gateway to get every pack's tools listed\ndirectly, instead of just this one's:\n\n```json\n{\n  \"mcpServers\": {\n    \"pipeworx\": {\n      \"url\": \"https://gateway.pipeworx.io/mcp\"\n    }\n  }\n}\n```\n\nBoth URLs reach the same gateway and the same 1558+ data sources. The\nonly difference is which pack's tools are listed **directly**; `ask_pipeworx`\nreaches all of them from either one.\n\n## Standalone (no gateway account)\n\nThis package also runs as a local stdio MCP server — no Pipeworx account, no\ngateway round-trip:\n\n```json\n{\n  \"mcpServers\": {\n    \"epstein\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@pipeworx/mcp-epstein\"]\n    }\n  }\n}\n```\n\nOr run it directly to confirm it starts:\n\n```bash\nnpx -y @pipeworx/mcp-epstein\n```\n\nIt speaks MCP over stdin/stdout and answers `initialize`/`tools/list`/`tools/call`\nfor **only** this pack's tools — none of the shared meta-tools the gateway\nconnection above adds. Same source, same tools, no ask_pipeworx routing.\n\n## Using with ask_pipeworx\n\nInstead of calling tools directly, you can ask questions in plain English —\nthis works on the pack endpoint above as well as on the full gateway:\n\n```\nask_pipeworx({ question: \"your question about Epstein data\" })\n```\n\nThe gateway picks the right tool and fills the arguments automatically.\n\n## More\n\n- [Docs and guides](https://pipeworx.io/docs)\n- [pipeworx.io](https://pipeworx.io)\n\n## License\n\nMIT\n",
  "bytes": 11255,
  "sha": "380476888e73647818f34591f7488d544751f518ceeb111d0bb93e451bb444b3",
  "repo_slug": "pipeworx-io/mcp-epstein",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_pipeworx_io_epstein_e9e8229c/readme"
}