# LOGOS — Scripture, for code

The Word of God in 11 translations, readable by machines and agents. A free, non-commercial **REST API** for any application, and a **Model Context Protocol (MCP) server** for AI coding assistants. No authentication, no rate limit, no tracking.

## REST API

**Base URL:** `https://www.logos77.com/api`

The Logos77 API returns Bible passages as JSON. Because scripture does not change, responses are cached at the edge and served in milliseconds from anywhere in the world. Every response includes a **deep link** back into the reader, so any quote you serve can always be opened in full context.

- **Authentication:** none required.
- **License:** the translations served are public domain. Free, strictly non-commercial.

## Getting started

Every endpoint accepts an optional `lang` parameter (defaults to English KJV). Here is a first verse.

```bash
curl "https://www.logos77.com/api/passage?lang=en&book=John&chapter=3&verse=16"
```

```js
const res = await fetch("https://www.logos77.com/api/passage?lang=en&book=John&chapter=3&verse=16");
const data = await res.json();
console.log(data.verses[0].text);
```

```json
{
  "reference": "John 3:16",
  "lang": "en",
  "lang_label": "English (KJV)",
  "book": "John",
  "chapter": 3,
  "verses": [
    { "verse": 16, "text": "For God so loved the world, that he gave his only begotten Son..." }
  ],
  "deep_link": "https://logos77.com/#John-3-16",
  "total_verses_in_chapter": 36
}
```

## Endpoints

Eight endpoints, each following the same response shape. All return JSON and honor `Cache-Control`.

### GET /api/passage
> Look up a verse, verse range, or full chapter

| Parameter | Type | Default | Description |
|---|---|---|---|
| `lang` | string | en | Language code. Defaults to 'en' (English/KJV). Accepts the language code, the verse-data name, or a full subdomain. |
| `book` | string | **required** | Book name in the translation's native language (e.g. 'John' for KJV, 'Jean' for Martin, 'Johannes' for Luther). |
| `chapter` | integer | **required** | Chapter number (1-based). |
| `verse` | string | omitted = full chapter | Verse or verse range. Omit to return the full chapter. Format: `^\d+(-\d+)?$`. |

```bash
curl "https://www.logos77.com/api/passage?book=John&chapter=3&verse=16-18"
```

Cache: `immutable, 1 year`

### GET /api/votd
> Deterministic verse of the day

| Parameter | Type | Default | Description |
|---|---|---|---|
| `lang` | string | en | Language code. Defaults to 'en' (English/KJV). Accepts the language code, the verse-data name, or a full subdomain. |

```bash
curl "https://www.logos77.com/api/votd?lang=en"
```

Cache: `immutable, 1 year`

### GET /api/random
> Random verse

| Parameter | Type | Default | Description |
|---|---|---|---|
| `lang` | string | en | Language code. Defaults to 'en' (English/KJV). Accepts the language code, the verse-data name, or a full subdomain. |

```bash
curl "https://www.logos77.com/api/random?lang=ta"
```

Cache: `not cached`

### GET /api/search
> Full-text search within a translation

| Parameter | Type | Default | Description |
|---|---|---|---|
| `lang` | string | en | Language code. Defaults to 'en' (English/KJV). Accepts the language code, the verse-data name, or a full subdomain. |
| `q` | string | **required** | Search query text. |
| `limit` | integer | 20 | Maximum number of results (1-100, default 20). |

```bash
curl "https://www.logos77.com/api/search?q=love&lang=en&limit=5"
```

Cache: `1 day`

### GET /api/through
> Read continuously through a translation

| Parameter | Type | Default | Description |
|---|---|---|---|
| `lang` | string | en | Language code. Defaults to 'en' (English/KJV). Accepts the language code, the verse-data name, or a full subdomain. |
| `group` | string | — | Read one continuous canonical group instead of a manual range: a group tag, label or alias (e.g. 'OT_LAW', 'Torah', 'Pauline Epistles'). Mutually exclusive with 'from', 'from_after' and 'to'. Non-continuous groups return an error — list them with GET /api/groups. |
| `from` | string | 0 (first verse) | Start bound: whole-Bible 0-based index (bare integer) or native reference (book, 'Book Ch', or 'Book Ch:V'). May come after 'to' to read through the end of the Bible back to Genesis. Omit to start at the first verse (Genesis 1:1). |
| `from_after` | string | — | Resume strictly after a reference (or index) instead of starting at it — e.g. 'John 3:16'. Survives data revisions that shift integer indexes; overrides 'from'. |
| `to` | string | end | End bound, same forms as 'from', or 'end'. Defaults to 'end' (last verse). |
| `limit` | integer | — | Maximum verses per slice (1-4096). Omit to return as much of the range as fits the slice caps at once. |

```bash
curl "https://www.logos77.com/api/through?from=Psalms+150&to=Psalms+1&limit=5"
```

Cache: `immutable, 1 year`

### GET /api/books
> List the books of a translation

| Parameter | Type | Default | Description |
|---|---|---|---|
| `lang` | string | en | Language code. Defaults to 'en' (English/KJV). Accepts the language code, the verse-data name, or a full subdomain. |

```bash
curl "https://www.logos77.com/api/books?lang=ta"
```

Cache: `immutable, 1 year`

### GET /api/languages
> List the available translations and their script properties

| Parameter | Type | Default | Description |
|---|---|---|---|


```bash
curl "https://www.logos77.com/api/languages?"
```

Cache: `immutable, 1 year`

### GET /api/groups
> List canonical book groupings for reading plans

| Parameter | Type | Default | Description |
|---|---|---|---|
| `lang` | string | en | Language code. Defaults to 'en' (English/KJV). Accepts the language code, the verse-data name, or a full subdomain. |

```bash
curl "https://www.logos77.com/api/groups?group=Torah"
```

Cache: `immutable, 1 year`


## Reading plans (book groups)

`GET /api/groups` lists the traditional, overlapping book groupings — the Law, History, Wisdom, Major and Minor Prophets, the Gospels, Paul's Letters, the General Letters, Revelation, cross-cutting groups (the whole Hebrew Bible, the whole Bible) and traditional subsets (the Synoptics, the Johannine writings, the Prison and Pastoral letters, the Deuteronomic and Post-exilic histories). Groups are **non-exclusive**: a book may belong to several. Every group carries its native book names, inclusive 0-based ranges, chapter/verse totals, and `contiguous` / `start` / `end` so you can plan a reading program.

Read one continuous group in a single loop segment by passing its tag, label, or alias to `/api/through`:

```bash
curl "https://www.logos77.com/api/through?group=Torah&limit=5"
```

`group` is mutually exclusive with `from` / `from_after` / `to` (a 400 if combined) and only **continuous** groups are readable this way — non-contiguous groups (e.g. the Johannine corpus) report `contiguous: false` and must be read book by book. The response echoes the resolved group as `group: { tag, label }`.

### Groups reference (the full Canonical Schema)

This is the complete Canonical Schema of the Bible — the same 23 overlapping, non-exclusive groups returned by `GET /api/groups`. Book names and totals are the **English (KJV)** rendering; every other translation localizes `books` (fetch `/api/groups?lang=<lang>`). Tags, labels and aliases are language-independent and matching is case-, diacritic- and punctuation-insensitive, so `OT_LAW`, `ot_law`, `ot law`, `Torah` and `pentateuch` all resolve to the same group. Ranges are **inclusive** 0-based book indexes into the canonical 66-book order. Every row whose `Continuous` is `yes` can be read in one loop segment via `/api/through?group=<tag|label|alias>`.

| Tag | Label | Aliases | Testament | Ranges (inclusive) | Books | Chapters | Verses | Continuous |
|---|---|---|---|---|---|---|---|---|
| `OT_LAW` | the Law | Torah, Pentateuch, Five Books of Moses | ot | 0–4 | Genesis, Exodus, Leviticus, Numbers, Deuteronomy | 187 | 5852 | yes |
| `OT_HIST` | History | Historical Books | ot | 5–16 | Joshua, Judges, Ruth, 1 Samuel, 2 Samuel, 1 Kings, 2 Kings, 1 Chronicles, 2 Chronicles, Ezra, Nehemiah, Esther | 249 | 7018 | yes |
| `OT_WIS` | Wisdom | Poetry, Poetic Books, Wisdom Literature | ot | 17–21 | Job, Psalms, Proverbs, Ecclesiastes, Solomon's Song | 243 | 4785 | yes |
| `OT_MAJOR` | Major Prophets |  | ot | 22–26 | Isaiah, Jeremiah, Lamentations, Ezekiel, Daniel | 183 | 4440 | yes |
| `OT_MINOR` | Minor Prophets | The Twelve, Twelve Prophets, Book of the Twelve | ot | 27–38 | Hosea, Joel, Amos, Obadiah, Jonah, Micah, Nahum, Habakkuk, Zephaniah, Haggai, Zechariah, Malachi | 67 | 1050 | yes |
| `OT_PROPHETS_BROAD` | the Prophets | Prophets (New Testament sense), Prophets outside the Law | ot | 5–38 | Joshua, Judges, Ruth, 1 Samuel, 2 Samuel, 1 Kings, 2 Kings, 1 Chronicles, 2 Chronicles, Ezra, Nehemiah, Esther, Job, Psalms, Proverbs, Ecclesiastes, Solomon's Song, Isaiah, Jeremiah, Lamentations, Ezekiel, Daniel, Hosea, Joel, Amos, Obadiah, Jonah, Micah, Nahum, Habakkuk, Zephaniah, Haggai, Zechariah, Malachi | 742 | 17293 | yes |
| `OT_PROPHETS_NARROW` | the Nevi'im | Nevi'im, Neviim, Former and Latter Prophets | ot | 5–6, 8–11, 22–23, 25–38 | Joshua, Judges, 1 Samuel, 2 Samuel, 1 Kings, 2 Kings, Isaiah, Jeremiah, Ezekiel, Daniel, Hosea, Joel, Amos, Obadiah, Jonah, Micah, Nahum, Habakkuk, Zephaniah, Haggai, Zechariah, Malachi | 742 | 17293 | no |
| `OT_ALL` | Old Testament | the Law and the Prophets, Hebrew Scriptures | ot | 0–38 | Genesis, Exodus, Leviticus, Numbers, Deuteronomy, Joshua, Judges, Ruth, 1 Samuel, 2 Samuel, 1 Kings, 2 Kings, 1 Chronicles, 2 Chronicles, Ezra, Nehemiah, Esther, Job, Psalms, Proverbs, Ecclesiastes, Solomon's Song, Isaiah, Jeremiah, Lamentations, Ezekiel, Daniel, Hosea, Joel, Amos, Obadiah, Jonah, Micah, Nahum, Habakkuk, Zephaniah, Haggai, Zechariah, Malachi | 929 | 23145 | yes |
| `NT_GOSPEL` | Gospels | the Gospels, Four Gospels | nt | 39–42 | Matthew, Mark, Luke, John | 89 | 3779 | yes |
| `NT_ACTS` | Acts | Acts of the Apostles, Apostolic History | nt | 43 | Acts | 28 | 1007 | yes |
| `NT_PAUL` | Paul's Letters | Paul, Pauline Epistles, Letters of Paul, Epistles of Paul | nt | 44–56 | Romans, 1 Corinthians, 2 Corinthians, Galatians, Ephesians, Philippians, Colossians, 1 Thessalonians, 2 Thessalonians, 1 Timothy, 2 Timothy, Titus, Philemon | 87 | 2033 | yes |
| `NT_GEN` | General Letters | General Epistles, Catholic Epistles, Catholic Letters | nt | 57–64 | Hebrews, James, 1 Peter, 2 Peter, 1 John, 2 John, 3 John, Jude | 34 | 734 | yes |
| `NT_APOC` | Revelation | Apocalypse, Book of Revelation | nt | 65 | Revelation | 22 | 404 | yes |
| `NT_ALL` | New Testament | the New Testament, Christian Greek Scriptures | nt | 39–65 | Matthew, Mark, Luke, John, Acts, Romans, 1 Corinthians, 2 Corinthians, Galatians, Ephesians, Philippians, Colossians, 1 Thessalonians, 2 Thessalonians, 1 Timothy, 2 Timothy, Titus, Philemon, Hebrews, James, 1 Peter, 2 Peter, 1 John, 2 John, 3 John, Jude, Revelation | 260 | 7957 | yes |
| `NT_SYNOPTIC` | Synoptic Gospels | Synoptics | nt | 39–41 | Matthew, Mark, Luke | 68 | 2900 | yes |
| `NT_LUKAN` | Luke & Acts | Lukan Writings, Luke-Acts | nt | 41–43 | Luke, John, Acts | 73 | 3037 | yes |
| `NT_JOHANNINE` | Johannine Writings | Johannine Corpus, John's Writings | nt | 42, 61–63, 65 | John, 1 John, 2 John, 3 John, Revelation | 192 | 5057 | no |
| `NT_PRISON` | Paul's Prison Letters | Prison Epistles, Captivity Epistles | nt | 48–50, 56 | Ephesians, Philippians, Colossians, Philemon | 36 | 757 | no |
| `NT_PASTORAL` | Paul's Pastoral Letters | Pastoral Epistles | nt | 53–55 | 1 Timothy, 2 Timothy, Titus | 13 | 242 | yes |
| `OT_DEUTERONOMIC` | Deuteronomic History | Deuteronomistic History, Former Prophets | ot | 5–6, 8–11 | Joshua, Judges, 1 Samuel, 2 Samuel, 1 Kings, 2 Kings | 151 | 4401 | no |
| `OT_POSTEXILIC` | Post-exilic Books | Restoration Books | ot | 14–15, 36–38 | Ezra, Nehemiah, Haggai, Zechariah, Malachi | 526 | 11128 | no |
| `HEBREW_BIBLE` | Hebrew Bible | Tanakh, Tanach, Mikra | cross | 0–38 | Genesis, Exodus, Leviticus, Numbers, Deuteronomy, Joshua, Judges, Ruth, 1 Samuel, 2 Samuel, 1 Kings, 2 Kings, 1 Chronicles, 2 Chronicles, Ezra, Nehemiah, Esther, Job, Psalms, Proverbs, Ecclesiastes, Solomon's Song, Isaiah, Jeremiah, Lamentations, Ezekiel, Daniel, Hosea, Joel, Amos, Obadiah, Jonah, Micah, Nahum, Habakkuk, Zephaniah, Haggai, Zechariah, Malachi | 929 | 23145 | yes |
| `BIBLE_ALL` | the whole Bible | Scripture, Holy Scripture, the Bible | cross | 0–65 | Genesis, Exodus, Leviticus, Numbers, Deuteronomy, Joshua, Judges, Ruth, 1 Samuel, 2 Samuel, 1 Kings, 2 Kings, 1 Chronicles, 2 Chronicles, Ezra, Nehemiah, Esther, Job, Psalms, Proverbs, Ecclesiastes, Solomon's Song, Isaiah, Jeremiah, Lamentations, Ezekiel, Daniel, Hosea, Joel, Amos, Obadiah, Jonah, Micah, Nahum, Habakkuk, Zephaniah, Haggai, Zechariah, Malachi, Matthew, Mark, Luke, John, Acts, Romans, 1 Corinthians, 2 Corinthians, Galatians, Ephesians, Philippians, Colossians, 1 Thessalonians, 2 Thessalonians, 1 Timothy, 2 Timothy, Titus, Philemon, Hebrews, James, 1 Peter, 2 Peter, 1 John, 2 John, 3 John, Jude, Revelation | 1189 | 31102 | yes |

## Reading the whole Bible (chained requests)

Omit `from` to start at the first verse, and omit `to` to read to the end — a bare `GET /api/through` covers the entire canon (Genesis 1:1 to Revelation 22:21 in KJV). A whole Bible never fits in one response (each slice is capped at 4096 verses to stay under platform limits), so you walk it with `next_url`:

```js
let url = 'https://www.logos77.com/api/through'; // from/to omitted => the whole Bible
for (;;) {
  const r = await fetch(url);
  if (!r.ok) { await new Promise((s) => setTimeout(s, 750)); continue; } // re-issue the same URL — deterministic
  const s = await r.json();
  s.verses.forEach((v, k) => { if (v.index !== s.from_index + k) throw new Error('discontinuity'); }); // optional contiguity check
  if (!s.truncated || !s.next_url) break; // else done
  url = s.next_url; // self-contained: lang, integer from/to, and limit
}
```

The chain is failsafe by construction:
- Every call is stateless and pure — `(lang, from, to, limit)` fully determines the slice, and responses are cached immutable at the edge, so a dropped request can be re-issued with an identical result.
- `next_url` / `prev_url` are self-contained, so you can resume from the last URL at any time and retries are identical.
- Slices align on integer bounds, so changing `limit` mid-walk never gaps or overlaps.
- Stop exactly when `truncated` is `false`. A whole Bible is at most 8 requests in every translation.

Indexes are stable within a deployment but can shift if verse data is revised. To resume at a point in a way that survives that, anchor on a verse's **reference** instead of its index: `from_after=<reference of your last received verse>` starts strictly after that verse. If a stale index ever returns a gap, re-anchor with `from_after` rather than restarting — at most one verse is re-read. A full restart of the remaining range is only needed if the reference itself no longer resolves (a book renamed or removed).

For the canonical book names in each translation, see `GET /api/books?lang=<lang>` — that is the vocabulary `book`, `from`, and `to` accept.

## Languages

The `lang` parameter (or MCP `lang` argument) selects the translation. **Book names are in the native language** of each translation — for example, John is `John` in KJV, `Jean` in Martin, and `Johannes` in Luther. Fetch `GET /api/books?lang=<lang>` to list the 66 canonical native names, or `GET /api/languages` to enumerate every translation with its script properties.

| Code | Translation | Subdomain |
|---|---|---|
| `en` | English (KJV) | logos77.com |
| `en-gb` | English (Geneva) | gb.logos77.com |
| `de` | German (Luther) | de.logos77.com |
| `fr` | French (Martin) | fr.logos77.com |
| `es` | Spanish (RVG) | es.logos77.com |
| `ru` | Russian (Synodal) | ru.logos77.com |
| `zh-hant` | Chinese Traditional (CKJV) | hk.logos77.com |
| `zh-hans` | Chinese Simplified (CKJV) | cn.logos77.com |
| `my` | Burmese (Judson) | my.logos77.com |
| `ar` | Arabic (SVD) | ar.logos77.com |
| `ta` | Tamil | ta.logos77.com |

`lang` also accepts the verse-data name or a full subdomain (e.g. `tamil` or `ta.logos77.com`).

## Non-Latin scripts & embedded / low-memory / small-display clients

Every response is **UTF-8** JSON (`Content-Type: application/json; charset=utf-8`), has no BOM, and is **uncompressed unless the client asks for it** — send `Accept-Encoding: identity` on microcontrollers and never request gzip unless you can decompress. This holds across every transport we expose: REST, MCP, and immutable-cached verses.

The guidance below applies to any display (LCD, OLED, TFT, LED matrix, e-ink, segment displays) and any controller (ESP32/Arduino, Raspberry Pi Pico, STM32, …).

### Glyph ≠ byte

UTF-8 encodes one code point in 1–4 bytes. Your renderer must group bytes into code points before drawing:

| Lang | Translation | Script | Direction | Max bytes/glyph | Combining marks |
|---|---|---|---|---|---|
| `en` | English (KJV) | Latin | ltr | 1 | no |
| `en-gb` | English (Geneva) | Latin | ltr | 1 | no |
| `de` | German (Luther) | Latin | ltr | 1 | no |
| `fr` | French (Martin) | Latin | ltr | 1 | no |
| `es` | Spanish (RVG) | Latin | ltr | 1 | no |
| `ru` | Russian (Synodal) | Cyrillic | ltr | 2 | no |
| `zh-hant` | Chinese Traditional (CKJV) | Han | ltr | 3 | no |
| `zh-hans` | Chinese Simplified (CKJV) | Han | ltr | 3 | no |
| `my` | Burmese (Judson) | Myanmar | ltr | 3 | yes |
| `ar` | Arabic (SVD) | Arabic | rtl | 2 | yes |
| `ta` | Tamil | Tamil | ltr | 3 | yes |

- **Latin/Cyrillic** map closely to one byte per character. Non-Latin does not: Tamil and Han are three bytes per glyph, Arabic two plus contextual shaping.
- **Glyph ≠ byte** — a Tamil verse is roughly 3 bytes per character; fixed `char[]` buffers and byte-offset slicing truncate mid-character and produce mojibake.
- **RTL — `ar`** must be laid out right-to-left.
- **Combining marks — `my`, `ta`, `ar`** use vowel signs and diacritics that attach to (or appear before) the base letter; render them as a unit, not as glyphs on separate advances.

### Rendering on small displays

- Bitmap displays (LCD/OLED/TFT/e-ink) need a **font that actually contains the script's code points** (e.g. an LVGL or Adafruit-GFX font converted from a Unicode TTF covering Tamil, Arabic, Han, or Myanmar). Without such a font, glyphs render as boxes/blank — a *rendering* failure, not a data failure.
- LED matrices, seven-segment, and ASCII character displays generally **cannot render non-Latin** — fall back to a romanized or reference label.
- e-ink: same font rules; prefer full refresh and text wrapping over partial updates.
- Test your pipeline with each translation's `sample` from `GET /api/languages` (or the script block in `/api/books`) — a fixed first-verse string for verifying decoding and font coverage before you process real requests.

### Minimal UTF-8 → code point

Decode bytes to code points before any layout or rendering work. Sketch in C:

```c
uint32_t utf8_next(const uint8_t **p, const uint8_t *end) {
  uint8_t b = *(*p)++;
  uint32_t cp = b;
  int extra = 0;
  if (b >= 0xF0) { cp = b & 0x07; extra = 3; }
  else if (b >= 0xE0) { cp = b & 0x0F; extra = 2; }
  else if (b >= 0xC0) { cp = b & 0x1F; extra = 1; }
  for (int i = 0; i < extra && *p < end; i++) cp = (cp << 6) | (**p++ & 0x3F);
  return cp; // code point; look this up in your font (glyph != byte)
}
```

> If text comes back wrong or blank after correct decoding, it is a font/rendering problem on the device — the bytes on the wire are standard UTF-8.

## Limits & caching

This API runs on a free tier, so it is designed to be extremely cache-friendly and self-limiting.

- No API key, no rate limit, no authentication.
- Passage, Verse-of-the-Day, Through-the-Bible, Book-list, Group-list, and Language-list responses are cached for a year at the edge. Once warm, they cost nothing to serve.
- Search is cached for one day.
- Random is not cached, so each call returns something new.
- An [OpenAPI specification](https://www.logos77.com/api/openapi) is available for tooling.

## MCP server

Logos77 also speaks the **Model Context Protocol**, so AI coding assistants (Claude, Cursor, others) can read scripture directly. Public, stateless, read-only — no API key required.

**Endpoint:** `https://www.logos77.com/mcp`

Protocol: [MCP Streamable HTTP](https://modelcontextprotocol.io). Transport over JSON-RPC 2.0.

### Tools

#### `fetch_passage`
Look up one or more verses of scripture. "book" is the book name in the translation's native language (e.g. John, Jean, Johannes). "verse" may be a single number or a range like "16-18"; omit it for the whole chapter.

| Parameter | Type | Default | Description |
|---|---|---|---|
| `book` | string | **required** | Book name in the translation's native language. |
| `chapter` | integer | **required** | Chapter number, 1-based. |
| `verse` | string | — | A verse (16) or a range (16-18). Omit for the full chapter. |
| `lang` | string | — | Language code (en, en-gb, de, fr, es, ru, zh-hant, zh-hans, my, ar, ta). Defaults to en. |

#### `verse_of_the_day`
Returns the same verse for everyone on a given day, advancing one verse per day so it never repeats within a reading cycle.

| Parameter | Type | Default | Description |
|---|---|---|---|
| `lang` | string | — | Language code. Defaults to en. |

#### `random_verse`
Returns a genuinely random verse of scripture.

| Parameter | Type | Default | Description |
|---|---|---|---|
| `lang` | string | — | Language code. Defaults to en. |

#### `search`
Case-insensitive substring search over verse text in a translation. Returns up to "limit" matching verses (1-100, default 20).

| Parameter | Type | Default | Description |
|---|---|---|---|
| `q` | string | **required** | Text to search for. |
| `lang` | string | — | Language code. Defaults to en. |
| `limit` | integer | — | Max results, 1-100. Defaults to 20. |

#### `read_through`
Read scripture in canonical order from "from" to "to". Omit "from" to start at the first verse, and omit "to" to read to the end — a request with only "lang" covers the whole Bible. Alternatively pass "group" (a group tag, label or alias — e.g. "OT_LAW", "Torah", "Pauline Epistles") to read one canonical group instead; group is mutually exclusive with from/from_after/to and only continuous groups are readable this way (see list_groups). The canon is a loop: when from comes after to, reading continues through the end of the Bible back to Genesis (e.g. from "Psalms 150" to "Psalms 1"). "from" and "to" are whole-Bible 0-based indexes or native references (book, "Book Ch", or "Book Ch:V"). Large ranges auto-slice: follow "next_url" (same to) to continue, one slice per call. To resume at a point in a way that survives data revisions, pass "from_after" with the reference of your last received verse instead of a "from" index. Returns up to "limit" verses per slice (1-4096, default 20).

| Parameter | Type | Default | Description |
|---|---|---|---|
| `from` | string | — | Start bound: whole-Bible 0-based index (e.g. 0) or native reference (e.g. "John", "John 3", "John 3:16"). May come after "to" to read through the end of the Bible back to Genesis. Omit to start at the first verse. |
| `from_after` | string | — | Resume strictly after a reference (or index) instead of starting at it — e.g. "John 3:16". Survives data revisions that shift integer indexes; overrides "from". |
| `to` | string | — | End bound, same forms as from, or "end". Defaults to "end". |
| `group` | string | — | Read one continuous canonical group instead of a manual range: a group tag, label or alias (e.g. "OT_LAW", "Torah", "Pauline Epistles"). Mutually exclusive with from/from_after/to. Non-continuous groups error — see list_groups. |
| `limit` | integer | — | Max verses per slice, 1-4096. Defaults to 20. |
| `lang` | string | — | Language code. Defaults to en. |

#### `list_books`
List the 66 books in canonical order for a translation, with their native names and chapter counts. Native book names are the vocabulary accepted by "book" (fetch_passage) and "from"/"to" (read_through), so this is how callers discover the correct referencing.

| Parameter | Type | Default | Description |
|---|---|---|---|
| `lang` | string | — | Language code. Defaults to en. |

#### `list_languages`
List every translation with its label, subdomain, and script metadata: writing direction (rtl/ltr), maximum UTF-8 bytes per code point, whether the script uses combining marks, and a sample verse for font/decoder verification. Use this to let a client (especially an embedded or small-display device) discover languages and adapt rendering before fetching any text.

| Parameter | Type | Default | Description |
|---|---|---|---|
_(no parameters)_

#### `list_groups`
List the traditional, overlapping book groupings (the Law, History, Wisdom, Major/Minor Prophets, Gospels, Paul's Letters, General Letters, Revelation, cross-cutting groups and traditional subsets) with per-translation native book names, inclusive whole-book index ranges, chapter/verse totals, contiguity, and a resolvable start/end span. Every continuous group has a "tag", "label" and "aliases" accepted by read_through's "group" parameter; non-contiguous groups (contiguous=false) must be read book by book.

| Parameter | Type | Default | Description |
|---|---|---|---|
| `lang` | string | — | Language code. Defaults to en. |

### Connect

Point your MCP client at the endpoint above:

```json
{
  "mcpServers": {
    "logos77": {
      "url": "https://www.logos77.com/mcp"
    }
  }
}
```

Every tool returns each verse with a canonical **deep link** back into the reader, e.g. `https://logos77.com/#John-3-16`, so any verse an assistant cites can always be opened in full context.

## Deep links

Every response includes a `deep_link` of the form:

```
https://<host>/#<Book>_<Chapter>-<Verse>
```

Book names with spaces are underscored (`2 Samuel` → `2_Samuel`), and non-Latin book names are percent-encoded, so every `deep_link` is **pure ASCII** (`https://ta.logos77.com/#%E0%AE%86…-10-15`). The reader percent-decodes fragments at launch and navigates straight to the verse.

_Generated from `api/openapi-spec.json`, `api/_shared.js`, `api/mcp.js`, and `vercel.json` by `scripts/generate-docs-md.mjs`. Do not edit by hand — the HTML page at [/docs](https://www.logos77.com/docs) is the human version._
