This repository is a downstream mirror. Source of truth lives in the
messai-aimonorepo; this mirror is updated on each release. Issues and Discussions are welcome here. PRs against this mirror will be redirected — see CONTRIBUTING.md.History was reset as part of the 2026 monorepo consolidation. Versions tagged before that (e.g.
v0.2.0) remain accessible as historical refs.
Note: this package was previously published as
@messai-io/mess-metagenomicsfrom the public mirrorMessai-io/MESS-Metagenomics. After the 2026-04-27 rename, the prior public repository has been archived and this is a fresh mirror. Pre-rename history lives at the archived repo and is not preserved here.
Canonical source: Postgres. Internally to the MESSAI monorepo, the
MicrobePrisma table (and child tables for cytochromes, shuttles, performance measurements, engineering events, omics studies, references, substrate-product pairs) is the source of truth. Thedata/mess-microbes.seed.jsonfile in this package is a downstream snapshot regenerated from the database before each release tag — same pattern asmess-parameters. External npm consumers see the JSON snapshot; internal tooling reads the database directly. See scripts/export-microbes-to-json.ts and scripts/seed-microbes-bootstrap.ts.
Curated database of microorganisms relevant to Microbial Electrochemical Systems (MES).
| File | Records | Correct verification |
|---|---|---|
data/mess-microbes.seed.json |
28 strains (schema v1.2) as of 2026-05-13 — verify before quoting | jq '.microbes | length' data/mess-microbes.seed.json |
schema/mess-microbe.schema.json |
1,657-line schema v1.2 with growth_kinetics, eet_mechanism, electrochemistry, biofilm, omics, engineering_history, commercial, bibliometrics, per-field confidence | Read file |
src/canonicalResolver.ts |
Microbe canonical-ID resolution v1.3 (alias map, inocula, priors) | 324 lines + 277-line tests |
src/electroactiveTaxa.ts |
Curated electroactive taxa list | Read file |
Common audit mistake:
jq 'length' data/mess-microbes.seed.jsonreturns 5 (the count of top-level object keys:last_updated,microbes,record_count,schema_version,source). That is not the microbe count. Usejq '.microbes | length'to get the actual record count (28).
Strains in v1.2 seed (verified — first 5 of 28):
- Geobacter sulfurreducens PCA
- Geobacter metallireducens GS-15
- Shewanella oneidensis MR-1
- Acetobacterium woodii
- Methanobacterium sp. strain YSL …plus 23 more. For the full live list, run:
jq -r '.microbes[].scientific_name' data/mess-microbes.seed.json
Snapshot of the prod DB Microbe table is also preserved at
papers/migration-history/db-seeds/seed-from-prod-latest/00-Microbe.sql.gz in
the monorepo (gitignored locally; the schema-v1.2.0 PostgreSQL COPY format dump
matches the JSON seed). Public mirror consumers only see the JSON seed.
The MES field uses two terms that overlap but aren't identical:
- Electroactive Microorganisms (EAM) — Logan 2019 / ISMET term. Organisms that transfer electrons to or from a solid electrode. Classical scope.
- MES-relevant microorganisms — broader. Any organism whose presence or activity matters in an MES reactor: electroactive species plus the fermenters that supply their substrates, the methanogens that compete or partner with them via DIET, the syntrophs that make obligate-anaerobe metabolism thermodynamically possible, and the contaminant degraders that do the reactor's "second job."
This database is MESS-broad by default, with is_electroactive as a
filterable boolean that recovers the classical EAM-only view in one line. See
docs/scope_and_views.md for the full rationale,
per-class field guide, and programmatic filtering recipes.
Functional classes covered:
| Class | Examples | Why in scope |
|---|---|---|
| Electrogens (outward EET) | G. sulfurreducens, S. oneidensis, R. palustris DX-1 | Primary current producers |
| Electrotrophs (inward EET) | S. ovata, A. ferrooxidans, Methanobacterium YSL | Cathode-side biocatalysts for MES |
| Bidirectional EET | G. sulfurreducens, cable bacteria, D. vulgaris | Both directions demonstrated |
| Cable bacteria | Candidatus Electronema | Long-range cm-scale conduction |
| DIET partners | Geobacter ↔ Methanothrix/Methanosarcina | Drive AD and methanogenic MES |
| Acetogens (MES) | S. ovata, C. ljungdahlii, M. thermoacetica | Primary MES product producers |
| Acetogens (non-MES) | A. woodii | Negative control: Na⁺ ATPase blocks MES |
| Methanogens | M. acetivorans, M. harundinacea, Methanobacterium YSL | MES products and competitors |
| Fermenters | C. butyricum, Enterococcus | Provide substrate to electrogens; produce H₂ |
| Syntrophs | Syntrophomonas wolfei | SCFA degradation; obligate H₂-consumer dependence |
| Sulfate-reducers | D. vulgaris | Common in mixed cultures |
| Phototrophs | Synechocystis PCC 6803, R. palustris DX-1 | Photo-MFCs, photo-MES |
| Denitrifiers | Thauera | Constructed-wetland MFCs, N removal |
| Pathogens of concern | P. aeruginosa, E. faecalis | Real but require BSL-2 |
npm install @messai-io/mess-microbesimport {
listMicrobes,
electroactive,
anodeSide,
cathodeSide,
byRole,
byDomain,
withCompleteness,
} from '@messai-io/mess-microbes';
// All 21 seeded organisms
const all = listMicrobes();
// EAM-only view (one-line filter to the classical scope)
const eams = electroactive();
// Anode-side organisms (MFC research)
const anode = anodeSide();
// Cathode-side / MES organisms
const cathode = cathodeSide();
// Filter by functional role
const acetogens = byRole('acetogen');
// Filter by taxonomic domain
const archaea = byDomain('Archaea');
// High-confidence records only
const reliable = withCompleteness('comprehensive', 'expert_reviewed');The full record shape is documented as TypeScript interfaces in
src/types.ts and as JSON Schema (draft-07) in
schema/mess-microbe.schema.json.
Source-of-truth data is at
data/mess-microbes.seed.json.
See also: cross-package joins — how to
resolve organism mentions to a canonical microbe id and join across
mess-parameters, mess-materials, and mess-methods.
You don't need the TypeScript package to use the data — the seed file is plain
JSON. The record count lives under microbes; a jq 'length' on the whole file
returns the number of top-level keys (7 in the current snapshot), not the
microbe count. Use jq '.microbes | length' for the real count.
import json
seed = json.load(open("data/mess-microbes.seed.json"))
microbes = seed["microbes"]
print(len(microbes), "records") # the true count
# Filter by the top-level is_electroactive boolean (classical EAM view)
eams = [m for m in microbes if m["is_electroactive"]]
print([m["id"] for m in eams])
# Look up one record by its canonical id
by_id = {m["id"]: m for m in microbes}
geo = by_id["geobacter_sulfurreducens_pca"]
print(geo["scientific_name"], geo["taxonomy"]["genus"])# Same queries with jq
jq '.microbes | length' data/mess-microbes.seed.json
jq -r '.microbes[] | select(.is_electroactive) | .id' data/mess-microbes.seed.jsonimport {
listMicrobes,
electroactive,
getMicrobe,
} from '@messai-io/mess-microbes';
const all = listMicrobes(); // every seeded record
const eams = electroactive(); // === all.filter(m => m.is_electroactive)
const geo = getMicrobe('geobacter_sulfurreducens_pca'); // by canonical id, or undefinedPaper text names organisms inconsistently ("G. sulfurreducens", "Geobacter sp.",
"mixed anaerobic sludge"). resolveCanonicalId maps such strings to a canonical
record id:
import {
resolveCanonicalId,
resolveCanonicalIds,
getMicrobe,
} from '@messai-io/mess-microbes';
const res = resolveCanonicalId('G. sulfurreducens');
// res === { canonical_id, rank, scientific_name, source, matched_alias, match_strategy }
// or null when there is no confident match.
if (res) {
const record = getMicrobe(res.canonical_id);
console.log(res.match_strategy, record?.is_electroactive);
}
// Bulk resolution keeps input order; unmatched entries come back as null.
const batch = resolveCanonicalIds([
'Shewanella oneidensis MR-1',
'unknown culture',
]);resolveCanonicalId returns null when it cannot confidently match — treat
that as "leave the canonical ID NULL", not as an error to retry with fuzzier
matching. Pass { allowSubstring: false } to disable the substring fallback.
import {
listElectroactiveTaxa,
listElectroactiveGenera,
genusIsElectroactive,
} from '@messai-io/mess-microbes';
const eamRecords = listElectroactiveTaxa(); // same set as electroactive()
const byGenus = listElectroactiveGenera(); // grouped: { genus, records, eet_directions }
const isEA = genusIsElectroactive('Geobacter'); // true21 organisms tiered by completeness:
- Tier 1 — comprehensive, model organisms (4): G. sulfurreducens PCA, S. oneidensis MR-1, S. ovata, E. faecalis.
- Tier 1/2 — partial, high-confidence (5): G. metallireducens GS-15, C. ljungdahlii, M. harundinacea, M. acetivorans, D. vulgaris Hildenborough.
- Tier 2 — partial, important community members (8): R. palustris DX-1, P. aeruginosa PA14, A. ferrooxidans, Candidatus Electronema, M. thermoacetica, A. woodii (negative control), C. butyricum, Synechocystis PCC 6803.
- Tier 3 — stubs / less-studied (4): Geoglobus ahangari, Methanobacterium electrotrophus YSL, Syntrophomonas wolfei, Thauera sp. MZ1T.
For consumers that pair the curated records with raw 16S / metagenomic input, three optional helper namespaces are exported:
import { fasta, diversity, validators } from '@messai-io/mess-microbes';
const result = await fasta.parseFASTA(content);
const metrics = diversity.calculateDiversityMetrics(taxaProfile);
const ok = validators.validateFASTAContent(content);These are utilities, not the primary API surface.
Each record carries data_quality.completeness (stub / partial /
comprehensive / expert_reviewed) and data_quality.confidence. The audit
script in coverage/audit.py classifies each record into
13 functional classes, applies per-class field rules
(coverage/applicability_rules.json), and reports declared-vs-computed
mismatches. The latest run is committed to
reports/coverage_audit.md.
cd coverage
python3 audit.pySee coverage/README.md for the full system and
data/SCIENTIFIC_INTEGRITY.md for the honesty
rule that governs how to set completeness.
python3 -c "
import json, jsonschema
data = json.load(open('data/mess-microbes.seed.json'))
schema = json.load(open('schema/mess-microbe.schema.json'))
for m in data['microbes']:
jsonschema.validate(m, schema)
print(f'{len(data[\"microbes\"])} records valid.')
"Schema bumped 1.1.0 → 1.2.0. Comprehensive sweep that closes all 13 previously-partial categories in the 23-category curation outline. All additions are optional; existing 21 records remain valid.
The 23-category outline (see
coverage/category_field_map.md) is now
23/23 ✅ Full at the schema level. Field population across records is a
separate concern — see "Data quality and audit" below.
Highlights:
- Structured
eet_mechanism.direct_transfer.cytochromes[]— per cytochrome:{name, localization, heme_count, midpoint_potential_v_vs_she, structural_data{pdb_id, alphafold_id, cryo_em_emdb_id}}. Replaces the flatkey_cytochromes: string[]. Geobacter PCA seeded with the full 14-cytochrome inventory; Shewanella MR-1 with the MtrCAB pathway. - Structured
mediated_transfer.shuttles[]—{molecule, is_endogenous, production_rate, midpoint_potential_v_vs_she}. Shewanella MR-1 seeded with riboflavin + FMN; Enterococcus faecalis with DMK + flavin. genome_metadata(assembly_level, size_bp, gc_content_pct, n_contigs, plasmids[]).engineering_history[]— strain isolation / evolution / engineering timeline with performance deltas. Geobacter PCA: KN400 ALE, omcZ knockout.omics_resources— transcriptomics, proteomics, metabolomics, lipidomics, single_cell, structural_data (PDB / EMDB / AlphaFold).commercial— patent_ids, companies, regulatory_status.bibliometrics— total_publications, most_cited_dois, reviews, conflicts_flagged (e.g. the PilA-vs-cytochrome-filament reversal).operational_characteristics— pure_vs_mixed performance, fouling resistance, substrate-switching recovery, load-change sensitivity.- Per-substrate growth kinetics (
growth_kinetics.per_substrate). light_requirementfor phototrophs (irradiance, wavelength, photoperiod).- Conductive-mineral-mediated DIET
(
community_interactions.conductive_mineral_mediation) — magnetite, biochar, etc. - Structured
genetic_tools(vectors, CRISPR systems, reporters, inducible promoters, knockout collections, transposon libraries). - Tolerance + shock response as structured entries (PAH/BTEX/ chlorinated/antibiotics × tolerance; pH/salinity/temperature/oxidative × shock).
data_quality.field_confidence(path-keyed) +expert_reviewers+version_history.taxonomy.is_type_strain,taxonomy.isolation, additional collection codes (NCIMB, CCUG, NRRL).
The full v1.0 → v1.2 change matrix is in
coverage/category_field_map.md#summary.
The reproducible curation patch set is at
scripts/curate_microbes_v1_2.py.
Schema 1.0.0 → 1.1.0. Three additive changes; existing records remain valid.
parent_record_id(top-level, optional). Links strain-level records to a species-level parent. Convention:geobacter_sulfurreducens(species) is the parent ofgeobacter_sulfurreducens_pcaandgeobacter_sulfurreducens_kn400(strains). Strain-level performance differences (PCA vs KN400) are too large to collapse, but rolling up by species at query time is cheap. Helpers:getStrainsOf(parentId),getParentOf(strainId).eet_mechanism.{direct_transfer,mediated_transfer}.completeness(mapped|partial|inferred|hypothesized|contested). Encodes "we know it does direct transfer but the cytochrome inventory is incomplete" as data, not as missing fields. Geobacter/Shewanella =mapped; most other genera =partialorinferred.electrochemical_performance.measurements[]. The biggest v1.1 change: per-measurement records carrying{type, value, value_unit, normalization_basis, conditions, citation, extraction_method}. Each entry is one observation from one paper under one set of conditions — one point in the cross-paper distribution. Power density CoV across mixed-culture MFC studies is ~1,285%; a single-value summary misleads. This is the join target for the MessAI extraction pipeline (MatSciBERT + ChemBERTa + Nougat). The legacy single-value fields (max_current_density,max_power_density, etc.) remain as "best representative" pointers and will deprecate whenmeasurements[]is consistently populated across the corpus. Helpers:getMeasurements(id, type?),getMeasurementDistribution(id, type).
- Curation depth before breadth. The schema is at 23/23 full; record
population is uneven (4 comprehensive, 14 partial, 3 stub). Phase B+C of v1.2
populated v1.2 fields on the 4 comprehensive records and 3 partial records as
worked examples; promoting more records past
partial → comprehensiveis the next curation push. - Extend
audit.pyto v1.2 fields (v1.3). Audit currently only evaluates v1.0/v1.1 fields and reports 6/21 declared=achieved. v1.3 will add per-class applicability rules for the v1.2 additions so the audit catches inflation across the full schema. - Backfill
electrochemical_performance.measurements[]from corpus extraction. The schema's join target for the MessAI extraction pipeline (MatSciBERT + ChemBERTa + Nougat) is in place; populating it with extracted measurements is the next data-side push. - License reclassification (MIT → CC BY 4.0 once seed dominates the package over the optional TS utilities).
- Cross-references with
mess-parametersslugs (e.g.biofilm_conductivityparameter ↔ Geobacter biofilm records). tsupDTS build fix before the first npm publish (pre-existing breakage; not blocking fortsc --noEmit).
See CONTRIBUTING.md. The audit must pass for any new or updated record before merge.
MIT — see LICENSE.