{
  "markdown": "<!-- textura-banner -->\n<div align=\"center\">\n  <a href=\"https://github.com/beepboop2025/narcoscope\"><img src=\"./banner.svg\" width=\"100%\" alt=\"narcoscope\" /></a>\n</div>\n\n![tests](https://github.com/beepboop2025/narcoscope/actions/workflows/tests.yml/badge.svg)\n![coverage](https://img.shields.io/badge/coverage-86%25-brightgreen)\n\n# 🌍 NarcoScope\n\n**Live: [narcoscope.com](https://narcoscope.com)** · evidence newsroom: **[narcoscope.com/#newsroom](https://narcoscope.com/#newsroom)**\n\n> Deployment status verified 2026-08-29: `narcoscope.com` is configured and is the canonical public origin. The apex serves the Vercel deployment; `www.narcoscope.com` serves the Railway deployment. Registry metadata and agents use the apex MCP endpoint.\n\nAn educational, public-good **data explorer** that makes the world's drug-trade\ndata *legible*. UNODC, INCB, and EUDA already publish street (retail) prices,\nprecursor-chemical prices, and trafficking-flow/seizure data — but it's buried in\ndense PDFs and CSVs most people can't read. This app is a **translation layer** on\ntop of that public data: clean charts, maps, and plain-English explanations.\n\n> **Mission:** democratize hard-to-read official drug data. Not a new data source —\n> a way to *understand* the existing one.\n\n## Agent and API access\n\n- RFC 9727 API Catalog: `https://narcoscope.com/.well-known/api-catalog`\n- OpenAPI: `https://narcoscope.com/openapi.json`\n- MCP manifest: `https://narcoscope.com/server.json`\n- Streamable HTTP MCP: `https://narcoscope.com/mcp`\n- Machine-readable product context: `https://narcoscope.com/.well-known/ai-catalog.json`\n- Agent-readable guide: `https://narcoscope.com/llms.txt`\n\n```json\n{\n  \"mcpServers\": {\n    \"narcoscope\": { \"url\": \"https://narcoscope.com/mcp\" }\n  }\n}\n```\n\nThe MCP service is read-only and returns JSON Schema-backed `structuredContent` for every tool. Version 1.3 supports both the stateless MCP 2026-07-28 discovery lane and the legacy 2025-06-18 initialization lane. It preserves official, illustrative, stale, unavailable, and restricted states rather than turning missing evidence into a score.\n\nThe staged/live/Registry boundary and mandatory publication sequence are recorded in [`docs/MCP-1.3.0-RELEASE-GATE.md`](docs/MCP-1.3.0-RELEASE-GATE.md).\n\n## What it shows\n\n- **Street Prices** — retail price trends by country, with a purity-adjusted view\n  and an *affordability* lens (price expressed as days of average local income).\n- **Precursor Flows & Prices** — trafficking corridors and precursor-chemical\n  prices, with source hubs (notably China) highlighted.\n- **Flow Map** — an Equal-Earth world map of corridor arcs, animated over time.\n- **Triangulation** — reads seizures against modalities that interdiction\n  agencies do *not* collect. Seizure volume moves with enforcement capacity at\n  least as much as with trafficking volume, and nothing inside the seizure data\n  separates the two; overdose mortality (vital-statistics registrars) and\n  wastewater load (environmental chemists) can. Where the modalities agree the\n  reading is credible; where they diverge, the divergence is the finding —\n  seizures up with consumption flat reads as an enforcement effect, consumption\n  up with seizures flat reads as expansion interdiction missed. Every verdict\n  reports how many independent modalities backed it and whether it survives\n  dropping any one of them. **Validation case:** Canadian cannabis 2019→2023\n  reads seizures −94% against measured wastewater consumption +69%. Canada\n  legalised cannabis in 2018, so the seizure collapse is enforcement stopping,\n  not demand stopping — and the tool says so rather than reporting a shrinking\n  market.\n- **Designations** — the ~2,600 entities on the OFAC SDN list under the\n  narcotics and transnational-crime authorities, searchable by name *or* by\n  OFAC-published alias, plus a jurisdiction network built from the countries\n  Treasury records each entity in. Betweenness and articulation-point analysis\n  show which jurisdictions hold the designated networks together.\n- **Evidence Newsroom** — a deterministic, offline-capable publication pipeline\n  with sentence-level citations and independent-source gates. Its first bounded\n  analysis keeps lawful trade, selected official incidents and US harm data in\n  separate evidence lanes, and states what cannot be joined or causally\n  attributed from the public record.\n- **Palimpsest BRI context** — a pinned, bounded source-readiness and national\n  economic context lane for CPEC, Gwadar, CMEC, Kyaukpyu and Balochistan. It\n  preserves official, independent and modeled claim classes plus unavailable\n  WDI coverage, but cannot enter drug-market, actor, route, guilt, political or\n  causal inference.\n- **Myanmar Focus** — province-level (Golden Triangle) detail: production regions,\n  civil-war conflict pressure, China/third-country precursor inflows, cross-border\n  corridor towns, and seized volumes. The intelligence layer fuses multi-source\n  evidence into per-region risk/confidence scores, flags cross-source\n  disagreement, weights sources by reliability tier, computes a\n  year-over-year risk trajectory (rising/falling/stable) so analysts see\n  momentum, flags a geographic **spillover watch** when a calm region\n  borders one that has already crossed the high-risk threshold, flags\n  **evidence staleness** (current/aging/stale) when a region's freshest\n  record predates the reporting year, discounting confidence accordingly,\n  and scores **precursor-corridor concentration** with a Herfindahl-Hirschman\n  Index (diversified/moderate/concentrated) to flag single-source supply\n  dependency — both a fragility signal and an interdiction priority.\n  Risk profiles and the evidence-graph ledger can be exported as CSV directly\n  from the briefing for offline analyst review.\n\nEvery view carries an auto-generated *\"In plain English\"* sentence and hover\ntooltips that explain each figure in human terms.\n\n## Screenshots\n\n> **Street Prices now ships official data**: UNODC World Drug Report 2025, Statistical Annex 8.1 (retail per-gram prices + purities, 2019–2023, 208 records across 69 countries), with World Bank GDP-per-capita (2024) powering the affordability lens. Flow-map, precursor and Myanmar figures remain illustrative pending ingestion — the in-app badge states exactly which is which.\n\nA dark, motion-led interface: a WebGL globe traces precursor corridors out of their\nsource hubs (coral) toward transit and destination nodes (cyan), headings reveal\nletter-by-letter, and sections spring in as you scroll. The immersive layer is fully\ngated behind `prefers-reduced-motion` and falls back to a lightweight 2D canvas on\nmobile / WebGL-less devices.\n\n![NarcoScope — WebGL hero globe](docs/screenshots/hero.png)\n\n**Street Prices** — price trends + affordability lens, with a plain-English summary:\n\n![Street Prices](docs/screenshots/street-prices.png)\n\n**Flow Map** — Equal-Earth world map of precursor corridors, animated by year:\n\n![Flow Map](docs/screenshots/flow-map.png)\n\n**Myanmar Focus** — province-level Golden Triangle detail:\n\n![Myanmar Focus](docs/screenshots/myanmar-focus.png)\n\n## Ethical scope (please read)\n\nThis tool reports **aggregate, published statistics** — country-level, annual, and\n(for focus regions) province-level — strictly for **awareness, education, and\nresearch**. By design it does **not** provide point-of-sale, real-time, sub-street,\nor navigable location data, and the precursor layer stores **logistics only** (what,\nhow much, where, control status) with **no chemistry, synthesis routes, or yields**.\nIt is not, and must not be used as, a guide to obtaining any substance.\n\n### Private ScamShield signal\n\nThe Hetzner analyst environment can ingest ScamShield's privacy-minimized\nTelegram aggregate for private review. This does not enter the website or its\nGit-backed datasets. A strict schema firewall rejects raw messages, exact IOCs,\nsource identifiers, universal-coverage claims, public-eligibility claims, and\nanything that drops the human-review requirement. The importer has no network\naccess and retains only aggregate counts, a source-file hash, hourly snapshots,\nand an append-only receipt ledger under `/var/lib/narcoscope-analyst/`.\n\nSee [`deploy/private-import/README.md`](deploy/private-import/README.md) for the\ntrust boundary and production service.\n\n### Named entities\n\nThe Designations tab names people and companies, which every other layer avoids.\nThe line it holds:\n\n- A **designation** is a published act of a government — an entity placed on a\n  list under a stated legal authority on a stated date. NarcoScope reports what\n  the government did. It does not characterise what the entity did, carries no\n  free-text allegation field, and a designation is **not** an adjudication of\n  guilt. OFAC delists; check the live list before relying on any row.\n- Addresses, passport and national-ID numbers and dates of birth are present in\n  the upstream OFAC file and are **deliberately not extracted**.\n- **Journalism and crowd-sourced trackers are leads, not records.** C4ADS,\n  InSight Crime, EIA, GASO and the rest are registered in the source registry\n  and read by the governed scraper into an analyst work queue. A named entity\n  reaches a bundled dataset only if it *also* appears on an official designation\n  list. The rule is written into `scripts/scrape/myanmar-sources.json` as\n  `verification_rule`.\n- The designation graph has **no entity-to-entity edges**, because OFAC\n  publishes none. Inventing them and running centrality over the result would\n  produce confident rankings of private individuals from a graph this tool made\n  up. `docs/ROADMAP-PARALLEL-ECONOMY.md` records the methods excluded on these\n  grounds, and why.\n\n## Data provenance\n\nMost bundled figures are now **official extracts**, regenerated by the pipeline\nfrom the sources below. What is still illustrative is named explicitly: the\nMyanmar region-level flow volumes and the precursor price series (INCB publishes\nno precursor prices). The in-app badge states which is which, and every\ngenerated dataset carries a provenance header naming its source, retrieval date\nand extraction rules.\n\n- UNODC — Drugs: prices & World Drug Report — https://dataunodc.un.org\n- INCB — Precursors Report 2025 (exact audited PDF) — https://www.incb.org/incb/uploads/documents/Publications/AnnualReports/AR2025/Precursors_Report/E_INCB_2025_4_eng.pdf\n- CDC NCHS — VSRR provisional drug overdose death counts — https://data.cdc.gov/NCHS/VSRR-Provisional-Drug-Overdose-Death-Counts/xkb8-kh2a\n- Statistics Canada — drug metabolites in municipal wastewater — https://www150.statcan.gc.ca/t1/tbl1/en/tv.action?pid=1310087101\n- US Treasury OFAC — Specially Designated Nationals — https://sanctionslist.ofac.treas.gov/Home/SdnList\n- EUDA (EMCDDA) — price, purity & wastewater — https://www.euda.europa.eu/data\n- World Bank — GDP per capita — https://data.worldbank.org\n- ACLED / International Crisis Group — Myanmar civil-war context\n\nThe full registry spans automated datasets,\nmanual-step datasets, and investigative reports that feed the analyst work queue\nrather than the app — in [`scripts/pipeline/sources.json`](./scripts/pipeline/sources.json).\nEach entry records its licence, cadence, automation tier, and what it feeds.\nTwo entries are registered specifically so the reasoning is not relitigated:\nOpenSanctions publishes **no licence** on its bulk artifacts and is therefore a\nlookup pointer rather than a bundled dataset, and OCCRP Aleph's per-collection\nlicences forbid redistribution.\n\n**Wastewater comes from Canada, not Europe.** EUDA returns HTTP 403 to\nnon-browser clients (on the current URL, the legacy one, and the copy linked\nfrom data.europa.eu) and ACIC ships PDFs, so neither of the famous programmes\ncan be automated. Statistics Canada publishes the same measurement, at the same\ngrain, in the same SCORE unit, through a keyless API under an open licence — so\nthat is the bundled default, and Canada is the second fully-triangulated\ncountry. European and Australian coverage still needs a verified export through\nthe CSV panel.\n\nLoad real data through the **\"Load official data (CSV)\"** panel in the footer; each\nfile is parsed by `src/lib/ingest.ts` and bad rows are reported, not silently dropped.\nSee `src/lib/ingest-config-reference.md` for the column mapping.\n\nMyanmar conflict and precursor-flow source triage can be prepared with the\nPalimpsest-style governed scraper:\n\n```bash\nnpm run scrape:myanmar -- --out docs/sources/myanmar-observations.csv --pretty\n```\n\nThat output is an analyst work queue with excerpts and content fingerprints, not\ndirect app data; verify and code rows into the Myanmar civil-war / precursor CSV\nschemas before loading them.\n\nA **derived ontology** of every entity and relation type actually present in the\ndata is regenerated by `npm run ontology` into `docs/ontology/`. It is induced by\nobservation over the bundled datasets rather than generated by a language model:\nthe corpus is already typed and provenance-tagged, so the schema can be read off\nit directly, which removes the hallucination risk entirely. It is a draft for\nreview and is never auto-applied to `src/types.ts`.\n\nThe new **Enterprise Intel** tab adds an event/entity evidence graph, regional\nrisk scores, confidence/source-diversity indicators, and an evidence ledger for\nanalyst review. See `docs/ENTERPRISE_HARDENING.md` for the paper-backed design.\n\nThe **Evidence Newsroom** tab reads a checked-in dossier and receipt generated\nwithout network access or model calls. Publication requires sentence and visual\ncitations, active upstream-source independence for synthesis, a countercase,\nlimitations and causal/culpability safety checks. See\n[`docs/EVIDENCE_NEWSROOM.md`](./docs/EVIDENCE_NEWSROOM.md).\n\n### Evidence newsroom publication contract\n\nThe newsroom is visibly labelled **automated evidence analysis**, with\n`humanReviewStatus: not_recorded`. No generative model participates in its build,\nno expert or affected-person testimony is included, and it never simulates those\nhuman voices. Its initial article makes no named allegation, records right to\nreply as `not_required`, and publishes a correction/update history with stable\nrevision and content hashes.\n\nAn official record used by the build can support an attributed observation. An\nanalytical or methodological synthesis requires at least two independent,\nactively used official upstream groups; merely registering an available,\ncapability-only or unavailable source contributes zero corroboration. When the\ninputs lack a lawful-trade denominator, record-level join, adjudicated outcome or\ndefensible country allocation, the newsroom abstains. It does not turn origin\nlabels, administrative designations or a separate mortality trend into guilt or\ncausal attribution.\n\nPublication surfaces are:\n\n- app route: `/#newsroom`;\n- standalone HTML: `/news/china-linked-precursor-incidents-official-record.html`;\n- machine brief: `/news/china-linked-precursor-incidents-official-record.machine-brief.json`;\n- cited dossier: `/news/china-linked-precursor-incidents-official-record.dossier.json`;\n- JSON Feed: `/news/feed.json`; and\n- Atom feed: `/news/feed.xml`.\n\nRun `npm run news:build` to regenerate the offline bundle and\n`npm run news:check` to verify every checked-in byte. The production build runs\nthe stale-artifact check before TypeScript and Vite.\n\n## Tech\n\nReact 18 · Vite 8 · TypeScript · Recharts · react-simple-maps (world-atlas bundled\nlocally). The interface layer adds **Three.js / React Three Fiber** (a lazy-loaded\nhero globe with bloom post-processing — kept out of the initial bundle),\n**@react-spring/web** (physics-based letter/section reveals and animated counters),\nand **Lenis** (global smooth scroll) — all behind a `prefers-reduced-motion` guard.\nRuntime data store (`src/lib/dataStore.ts`) swaps sample → real data on load.\n\n## Develop\n\n```bash\nnpm install\nnpm run dev        # local dev server\nnpm run scrape:myanmar -- --pretty\nnpm run ontology   # regenerate docs/ontology/draft-ontology.{json,md}\nnpm run news:build # regenerate the deterministic evidence newsroom\nnpm run news:check # verify that checked-in newsroom artifacts are current\nnpm run bridge:palimpsest-bri:check # verify the pinned BRI artifact + hash\nnpm run build      # type-check (tsc) + production build → dist/\nnpm run preview    # preview the build\nnpm run typecheck  # tsc --noEmit\nnpm test           # run unit tests (Vitest)\n```\n\n## Deploy (Vercel)\n\nThe repo is Vercel-ready (`vercel.json` pins the Vite framework). Either:\n\n- **Dashboard:** import the Git repo at vercel.com — zero config, auto-detected.\n- **CLI:** `npx vercel` (preview) / `npx vercel --prod` (production).\n\n## Data pipeline\n\n`npm run data:refresh` fetches the automatable open sources (UNODC WDR\nannexes, World Bank GDP, CDC VSRR mortality, OFAC SDN designations),\nregenerates the bundled datasets, and validates\nthem against the test suite. Individual refreshes: `npm run data:overdose`,\n`npm run data:designations`. A quarterly GitHub Action does the same and\nopens a PR when the data changes. The full source registry (including the\nmanual and API-key sources not yet wired in) lives in\n[`scripts/pipeline/sources.json`](./scripts/pipeline/sources.json); the\nplaybook is [`docs/DATA_PIPELINE.md`](./docs/DATA_PIPELINE.md).\n\n## Status / TODO\n\n- ~~`purityAdjustedPrice()` is an intentional stub~~ **done** — it now returns\n  price per pure gram and refuses to adjust when purity is unknown (an honest\n  `n/a` beats comparing a cut street price against a pure one). See the editorial\n  note in `src/lib/metrics.ts`.\n- ~~Load and **verify** real UNODC/INCB data~~ **Street prices and qualified\n  precursor-flow records: done** (WDR 2025 Annex 8.1 and the paragraph-located\n  INCB 2025 precursor report). Remaining: a citable precursor-price series and\n  the Myanmar dataset.\n- **Wastewater now ships (Canada).** Extending it to Europe or Australia still\n  needs a manually-fetched EUDA or ACIC export — both publishers block\n  automation. Each one added is another country where divergence detection works.\n- A **second designating authority** for the Designations tab (it is OFAC-only\n  today). The UN Consolidated list was evaluated and ruled out — it is a\n  counter-terrorism instrument with almost no narcotics designations; EU\n  Sanctions Map is the live candidate. See [`docs/ROADMAP-PARALLEL-ECONOMY.md`](./docs/ROADMAP-PARALLEL-ECONOMY.md)\n  for the ordered backlog and for the methods excluded on ethical or\n  data-quality grounds.\n\n## License\n\n[MIT](./LICENSE) — free to use, adapt, and build on, with attribution.\n",
  "bytes": 18644,
  "sha": "bf5030334044324226e69e9195fc4b00001c351f51ae9af94518a808bcb1cfe8",
  "repo_slug": "beepboop2025/narcoscope",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_beepboop2025_narcoscope_f71c7c0b/readme"
}