{"id":50885945,"url":"https://github.com/kbennett2000/concord","last_synced_at":"2026-06-15T17:01:40.623Z","repository":{"id":362560236,"uuid":"1259547337","full_name":"kbennett2000/concord","owner":"kbennett2000","description":"A self-hosted, LAN-first, read-only Scripture API serving multiple public-domain Bible translations from one canonical source.","archived":false,"fork":false,"pushed_at":"2026-06-12T23:22:40.000Z","size":30921,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-13T01:13:10.340Z","etag":null,"topics":["bible","bible-api","church-tech","fastapi","fts5","homelab","lan-first","offline-first","public-domain","scripture","self-hosted","sqlite"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kbennett2000.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-04T16:04:51.000Z","updated_at":"2026-06-12T23:22:44.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/kbennett2000/concord","commit_stats":null,"previous_names":["kbennett2000/concord"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/kbennett2000/concord","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kbennett2000%2Fconcord","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kbennett2000%2Fconcord/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kbennett2000%2Fconcord/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kbennett2000%2Fconcord/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kbennett2000","download_url":"https://codeload.github.com/kbennett2000/concord/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kbennett2000%2Fconcord/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34372130,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-15T02:00:07.085Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bible","bible-api","church-tech","fastapi","fts5","homelab","lan-first","offline-first","public-domain","scripture","self-hosted","sqlite"],"created_at":"2026-06-15T17:01:39.500Z","updated_at":"2026-06-15T17:01:40.610Z","avatar_url":"https://github.com/kbennett2000.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Concord — Scripture, served locally.](docs/banner.svg)\n\n# Concord\n\nA self-hosted, LAN-first, read-only Scripture API. It serves multiple public-domain Bible\ntranslations — aligned by book, chapter, and verse — from one canonical SQLite source. It\nalso does semantic search: ask for verses by idea, not just keyword, and the right passages\ncome back even when they don't share a word. And it knows where Scripture happened: ask where\na place is, or which places a passage names, and the coordinates come back — honestly marked\nwhen a location is genuinely unknown. Once built, it runs entirely offline: no CDNs, no\ntelemetry, no phone-home.\n\n### Where to next?\n\n- **A developer who wants to get hands-on?** → [Quick start](#quick-start), including [semantic search](#semantic-search) and the new [geography](#geography) endpoints.\n- **Here because Scripture matters to you, and you're curious what this is?** → [What is this, really?](#what-is-this-really)\n- **Looking for a polished Bible app to actually use?** → [songbird](https://github.com/kbennett2000/songbird) (desktop) or [soap-journal-mobile](https://github.com/kbennett2000/soap-journal-mobile) (phone).\n- **Want your AI assistant to answer Bible questions from a real Bible — not from memory?** → [concord-mcp](https://github.com/kbennett2000/concord-mcp) connects Concord to Claude.\n\n## What is this, really?\n\nHi. You found Concord, and you might be wondering what you're looking at.\n\nConcord is a small piece of software that serves Bible verses. It runs on a computer you\n(or your church, or your office) controls — not on someone else's cloud. Once it's set up,\nit works offline, forever, without phoning home to anyone. It can also find verses by\n*meaning* — ask for \"verses about anxiety\" and it surfaces the passages that fit, even the\nones that never use the word. And it can tell you *where* — where Capernaum is, or which\nplaces Paul passed through in a chapter — and it stays honest when a location is lost to\nhistory rather than guessing at one.\n\nBut here's the thing: **Concord isn't an app you use directly.** It's the foundation that\nother apps are built on. Think of it like the foundation of a house — essential, but you\ndon't live in the foundation. You live in the house.\n\n### Are you looking for a Bible app to actually use?\n\nIf you want a polished, end-user app that lets you read, journal, take notes, and reflect on\nScripture — try [songbird](https://github.com/kbennett2000/songbird) (desktop) or\n[soap-journal-mobile](https://github.com/kbennett2000/soap-journal-mobile) (phone). They're\nprobably what you actually want.\n\nsongbird is built on top of Concord — a polished desktop app that runs against this very\n`/v1` surface. soap-journal-mobile is offline-first and goes anywhere, so it runs on its own\nand doesn't depend on Concord's LAN server at all.\n\nAnd if the way you'd rather reach for Scripture is by *asking your AI assistant* —\n[concord-mcp](https://github.com/kbennett2000/concord-mcp) connects Concord to Claude, so it\nanswers from verses it actually looked up in your instance (quoted with a reference like\n`John 3:16 (KJV)`) instead of reciting them from memory.\n\nConcord itself is for the builders.\n\n### \"But could I build something with this? I've never coded.\"\n\nMaybe. Honestly.\n\nThe hardest part of building software is usually the data — getting it, cleaning it,\norganizing it. Concord hands you 13 English Bible translations plus the original-language\ntexts — the SBL Greek New Testament and the Hebrew Old Testament — fully aligned, ready to\nquery, in a single tiny request. The \"hard part\" is\nalready done.\n\nWhat's left is just *asking it questions* and *showing the answers*. Both of those are more\napproachable than they sound, and there's a growing universe of tutorials and AI assistants\nthat can walk you through it patiently.\n\nA tutorial written for someone in exactly your shoes is here:\n**[concord-tutorial-web](https://github.com/kbennett2000/concord-tutorial-web)** — a free,\nfive-lesson course that takes you from \"what's an API?\" to a real app you built yourself,\nrunning on your own computer. No experience needed. If that \"I've never coded\" voice is you,\nstart there — and when you've finished, **[concord-tutorial-react](https://github.com/kbennett2000/concord-tutorial-react)**\npicks up right where it leaves off and walks you into React — and\n**[concord-tutorial-ai](https://github.com/kbennett2000/concord-tutorial-ai)** finishes the\nladder: the AI everyone is talking about, taught to look Scripture up in *your* Concord instead\nof remembering it. Still no experience needed. (The next sections of this README are written for\ndevelopers — but the courses were written for you.)\n\n## Quick start\n\nRequirements: Docker, Docker Compose, a LAN.\n\n```bash\ngit clone https://github.com/kbennett2000/concord\ncd concord\ndocker compose up -d\ncurl localhost:8000/healthz\n```\n\nThat last line returns JSON with translation and verse counts. Open `localhost:8000/docs` in\na browser for interactive Swagger documentation — it works fully offline.\n\nPrefer not to build? Pull the prebuilt image instead — see [Deployment](#deployment).\n\nWant a verse?\n\n```bash\ncurl 'localhost:8000/v1/verses/John%203:16'\n```\n\nOr find verses by meaning:\n\n```bash\ncurl 'localhost:8000/v1/semantic-search?q=do+not+be+anxious'\n```\n\nThe full API reference is in [`docs/API.md`](docs/API.md). Configuration, deployment, and the\nrest are below.\n\n## What's in the box\n\nTwenty-seven endpoints. Each is documented in full — with real request/response examples — in\n[`docs/API.md`](docs/API.md).\n\n| Endpoint | What it does |\n|---|---|\n| `GET /v1/verses/{ref}` | Fetch a verse, range, list, or chapter across one or more translations. |\n| `GET /v1/chapters/{book}/{chapter}` | Fetch a whole chapter, multi-translation aware. |\n| `GET /v1/search` | Full-text search — one translation, or across several at once with `?translations=`. |\n| `GET /v1/semantic-search` | Meaning-based search — find verses by idea, rendered in any translation. |\n| `GET /v1/cross-references/{ref}` | Cross-references for a verse, optionally with target text. |\n| `GET /v1/places` | Browse places, filtered by type, status, or name. |\n| `GET /v1/places/{id}` | One place's detail — coordinates, confidence, and how honestly it's located. |\n| `GET /v1/places/{id}/verses` | The verses that mention a place. |\n| `GET /v1/verses/{ref}/places` | The places a verse or passage names. |\n| `GET /v1/journeys` | Browse the curated biblical journeys (Paul's missionary journeys, the Exodus). |\n| `GET /v1/journeys/{id}` | One journey — its ordered stops resolving to real places, plus source and dating. |\n| `GET /v1/places/{id}/journeys` | The journeys that pass through a place (the reverse lookup). |\n| `GET /v1/translations/{translation}/notes/{book}/{chapter}` | Translator's, study, and text-critical notes for a passage — user-supplied, never shipped in the public image. |\n| `GET /v1/notes/search` | Keyword search over translator's notes — user-supplied, never shipped in the public image. |\n| `GET /v1/translations/{translation}/headings/{book}/{chapter}` | The section headings that anchor a chapter (\"The Creation\", \"The Beatitudes\"), per translation. |\n| `GET /v1/topics` | Browse topical-Bible subjects (Nave's), filtered by name or section. |\n| `GET /v1/topics/{id}` | One topic's detail — its verse count and any \"see also\" redirect. |\n| `GET /v1/topics/{id}/verses` | The verses curated under a topic, optionally with text. |\n| `GET /v1/verses/{ref}/topics` | The topics a verse or passage appears under. |\n| `GET /v1/strongs` | Browse the Strong's lexicon, filtered by lemma/transliteration/gloss or language. |\n| `GET /v1/strongs/{id}` | One Strong's entry — lemma, transliteration, gloss, and full definition. |\n| `GET /v1/strongs/{id}/verses` | The verses where a Strong's number occurs (a concordance), optionally with text. |\n| `GET /v1/verses/{ref}/words` | The tagged original-language tokens of a verse — surface, Strong's, morph, gloss. |\n| `GET /v1/random` | A random verse, optionally filtered by book or testament. |\n| `GET /v1/books` | The 66-book catalog with metadata. |\n| `GET /v1/translations` | The loaded translations with metadata. |\n| `GET /healthz` | Liveness plus row counts. |\n\nUnder the hood, Concord is three packages. `bible-core` is the engine — schema, loader,\nreference parser, and queries — with **zero web dependencies**, so a Python app can embed it\nin-process and skip HTTP entirely. `bible-semantic` is the embedding engine behind semantic\nsearch — also web-free. `bible-api` is the thin FastAPI layer that wraps them. The `/v1`\nprefix is a promise: encode against this surface with confidence.\n\n### Semantic search\n\n`GET /v1/semantic-search` finds verses by meaning. Ask for `verses about anxiety` and you get\nthe passages that fit — even ones that never use the word — ranked by closeness.\n\nThe search runs over one embedded translation, the **World English Bible (WEB)**, in\nmeaning-space. What it finds are verse *references*, so you can read them in whatever\ntranslation you want: add `?translation=KJV` and the same hits come back as KJV text. It runs\nfully offline like everything else — the embedding model is baked into the image, and nothing\nis ever sent anywhere.\n\n```bash\ncurl 'localhost:8000/v1/semantic-search?q=the+good+shepherd\u0026translation=KJV'\n```\n\nThe full parameters — `limit`, `min_score`, `include_text` — are in [`docs/API.md`](docs/API.md).\n\n### Geography\n\n`GET /v1/places` and its companions answer *where*. Every place has a stable id and is properly\ndisambiguated — the several Antiochs and Bethlehems are distinct entries, not one fuzzy point —\nand the link runs **both ways**: ask a place for its verses, or ask a verse (or a whole chapter)\nfor the places it names.\n\n```bash\ncurl 'localhost:8000/v1/verses/Acts+17/places'   # Athens, Berea, Thessalonica, Amphipolis, ...\n```\n\nWhat gives it character is honesty about uncertainty. **Concord never invents a pin.** A place it\ncan locate is `identified`, with coordinates (Jerusalem, 31.78°N 35.23°E). A place scholars place\ndifferently is `disputed` — a best-guess coordinate, flagged as contested. A place whose location\nis genuinely lost is `unknown`, with no coordinates at all rather than a fabricated one: the land\nof Nod, east of Eden, comes back honestly marked unknown. (Two more statuses round it out:\n`symbolic` for a name used non-literally, `multiple` for something itinerant like the tabernacle.)\nCoordinates are always named `latitude`/`longitude` fields — never a bare pair you could read\nbackwards.\n\nThe data is OpenBible.info's, **1,340 places** linked across the canon. The full parameters — the\nfilters, pagination, and the honest null-coordinate response — are in [`docs/API.md`](docs/API.md).\n\n### Topics\n\n`GET /v1/topics` answers *what about*. Browse curated subjects — \"Faith\", \"Care\", \"The Creation\" —\nfrom **Nave's Topical Bible** (5,319 topics), and the link runs **both ways**: ask a topic for its\nverses, or ask a verse for the topics it appears under.\n\n```bash\ncurl 'localhost:8000/v1/topics?q=anxiety'              # finds ANXIETY (→ see_also: care)\ncurl 'localhost:8000/v1/verses/Philippians+4:6/topics' # Care, Prayer, Thankfulness, ...\n```\n\nNave's own \"See X\" cross-references are preserved: a redirect topic carries a `see_also` pointer\nand no verses of its own (so `anxiety` points you to `care`, where the verses live). The full\nparameters — name/section filters, pagination, and `include_text` — are in\n[`docs/API.md`](docs/API.md).\n\n### Word study\n\n`GET /v1/strongs` answers *what does the original word mean*. Browse the **Strong's lexicon** —\nthe Greek lexicon from [STEPBible](https://github.com/STEPBible/STEPBible-Data) — by lemma,\ntransliteration, or gloss, and pull one entry's full definition. Ids are forgiving: `g0026`,\n`g26`, and `G26` all resolve to the same entry.\n\n```bash\ncurl 'localhost:8000/v1/strongs?q=love\u0026language=grc'   # ἀγαπάω (G25), ἀγάπη (G26), ...\ncurl 'localhost:8000/v1/strongs/G26'                   # ἀγάπη — \"love\", with full definition\n```\n\nAnd the link runs **both ways**, over the **SBL Greek New Testament** and the **Hebrew Old\nTestament** (each loaded as a translation — `?translation=SBLGNT` / `?translation=OSHB`): ask a\nStrong's number for every verse it appears in, or ask a verse for its tagged original-language words\n— each with its lemma, morphology, and gloss. Greek (`G…`) and Hebrew (`H…`) share one lexicon.\n\n```bash\ncurl 'localhost:8000/v1/strongs/G26/verses'            # every verse with ἀγάπη — a concordance\ncurl 'localhost:8000/v1/verses/John+3:16/words'        # the tagged Greek tokens of John 3:16\ncurl 'localhost:8000/v1/strongs/H430/verses'           # every verse with אֱלֹהִים (\"God\")\ncurl 'localhost:8000/v1/verses/Genesis+1:1/words'      # the tagged Hebrew tokens of Genesis 1:1\n```\n\nThe right text is chosen automatically — Hebrew (`OSHB`) for an `H…` id or an OT reference, Greek\n(`SBLGNT`) for a `G…` id or an NT reference — and `?text=` overrides it. The Hebrew OT uses\nEnglish/NRSV verse numbers (so it lines up with the English Bibles) and is served right-to-left\n(`direction: \"rtl\"` in `/v1/translations`). Aligning each English word to its underlying\nGreek/Hebrew token is deliberately out of scope.\n\n### Journeys\n\n`GET /v1/journeys` answers *where did they go*. A curated handful of well-known biblical\nitineraries — **Paul's three missionary journeys, his voyage to Rome, and the Exodus** — each an\n**ordered sequence of existing places**, so a map client can draw the route as a polyline.\n\n```bash\ncurl 'localhost:8000/v1/journeys'                 # the curated set\ncurl 'localhost:8000/v1/journeys/paul-first'      # 15 ordered stops, Antioch → ... → Antioch\ncurl 'localhost:8000/v1/places/a6c704a/journeys'  # which journeys pass through Pisidian Antioch\n```\n\nJourneys **reuse the geography** — every stop is a reference into the same place data (and its\nhonesty model), never new geography — so a stop the map can't pin (a low-confidence wilderness\nstation on the Exodus) is surfaced honestly rather than invented. And it stays honest about the\nroute itself: each journey is **one commonly proposed reconstruction**, carrying its `source` and a\n`note` saying so, dated as a whole. Competing routes, route variants, and segment-level dating are\ndeliberately out of scope. The itineraries follow the biblical narrative; the link runs **both\nways** (`/v1/places/{id}/journeys` is the reverse). Full parameters are in [`docs/API.md`](docs/API.md).\n\n## Configuration\n\nEvery setting has a sensible default; none are required. Set them in the host environment or\nin a `.env` file (`docker compose` reads both). See [`.env.example`](.env.example).\n\n| Variable | Default | Meaning |\n|---|---|---|\n| `BIBLE_API_PORT` | `8000` | Host port the API is published on. The container always listens on 8000 internally; this just remaps the host side. |\n| `CONCORD_CORS_ORIGINS` | `*` | Comma-separated allowed CORS origins. `*` suits a trusted LAN. |\n| `CONCORD_DEFAULT_TRANSLATION` | `KJV` | Translation used when `?translation(s)=` is omitted. Must be one that's loaded, or the API refuses to start. |\n| `BIBLE_DB_PATH` | `/app/bible.db` | Path to the database inside the container. |\n| `CONCORD_SEMANTIC_SEARCH` | `1` | Whether `/v1/semantic-search` is served. Set it to `0` to disable (skips loading the embedding model). |\n| `CONCORD_SEMANTIC_MAX_CONCURRENCY` | `2` | Max simultaneous semantic inferences; excess is shed with `503` + `Retry-After`. `0` disables the cap. Raise on beefier/AVX2 hardware. |\n| `CONCORD_SEMANTIC_TIMEOUT_S` | `10` | Per-inference wall-clock deadline (seconds); a query over budget is shed with `503` + `Retry-After`. `0` disables it. |\n\nChanging the port is one line:\n\n```bash\nBIBLE_API_PORT=9001 docker compose up -d   # now on localhost:9001\n```\n\n## Requirements\n\nConcord runs on modest, owned hardware. There are two tiers, depending on whether semantic\nsearch is on — measured, not guessed:\n\n| | Core API | + Semantic search |\n|---|---|---|\n| **Query latency** | instant (in-memory SQLite) | ~92 ms on a 2012 no-AVX2 desktop, ~42 ms on a modern machine — interactive |\n| **RAM** | ~256 MB | ~662 MB |\n| **To deploy** | \u003c100 MB image | ~450 MB compressed to transfer, ~1.4 GB on disk once loaded |\n| **CPU** | anything (even a Raspberry Pi) | x86-64 with AVX (2011+) or Apple Silicon; AVX2 is faster but not required |\n| **GPU** | none | none |\n| **Network** | none at runtime | none at runtime |\n\nTested on a 2012 Dell Optiplex 9010 — a $50 used desktop: semantic Scripture search in under\na tenth of a second, fully offline. If it runs there, it runs on whatever you've got.\n\nGeography doesn't move these numbers: it's a small set of data tables baked into `bible.db`,\nwith no model and no new runtime — the place lookups are instant SQLite reads like the rest of\nthe core API.\n\n## Deployment\n\nThe database, the embedding model, and the precomputed verse vectors are all **baked into\nthe image** at build time — no volumes, no separate data step. A fresh container is\nimmediately ready and identical to every other container built from the same source.\n\n**The easy path — pull the published image.** A prebuilt image is published to GHCR, so you\ncan skip the ~20-min build entirely and just pull it (no auth required):\n\n```bash\ndocker pull ghcr.io/kbennett2000/concord:v1.2.0     # or :latest\ndocker run -d -p 8000:8000 ghcr.io/kbennett2000/concord:v1.2.0\ncurl localhost:8000/healthz\n```\n\nThe image is `linux/amd64` and, like a locally-built one, runs fully offline once pulled. To\nuse it from compose, point the `image:` at the published tag instead of building locally. The\nbuild-from-source and `docker save`/`scp` paths below remain available — pulling is just the\nquickest way in.\n\nDeploy to a LAN host by building from source (replace `192.168.1.62` with yours):\n\n```bash\nrsync -a --exclude .git --exclude data/private ./ user@192.168.1.62:~/concord/\nssh user@192.168.1.62 'cd ~/concord \u0026\u0026 docker compose up -d'\n```\n\nThen from any LAN client: `curl http://192.168.1.62:8000/healthz`.\n\n**Build on a capable machine, run on a modest one.** Embedding the corpus happens once at\nimage-build time and takes ~20–30 minutes — fast on a recent CPU, but slow on an old one\n(an AVX2-less box could take an hour or more). So build the image where it's quick, then ship\nthe built image to the modest box rather than building there:\n\n```bash\ndocker save concord:latest | gzip \u003e concord.tar.gz          # on the capable machine (~450 MB)\nscp concord.tar.gz user@192.168.1.62:~/                      # to the LAN box\nssh user@192.168.1.62 'gunzip -c concord.tar.gz | docker load \u0026\u0026 docker compose up -d'\n```\n\nThe modest box only ever runs the fast query-time path. Querying works fully offline —\nverified with the network physically off (`docker run --network none …` still serves\n`/v1/semantic-search` and `/healthz`).\n\n**Verifying it's truly offline.** The image carries every asset it needs, including the\nSwagger UI bundle, so `/docs` renders with no internet at all:\n\n```bash\ndocker run --rm --network none -p 8000:8000 concord:latest \u0026\nsleep 6\ncurl -s localhost:8000/docs | grep -Eq 'jsdelivr|unpkg|fonts.googleapis' \\\n  \u0026\u0026 echo 'FAIL: reaches a CDN' || echo 'OK: /docs is fully self-hosted'\n```\n\nThe container starts healthy (the built-in healthcheck polls `/healthz`), and\n`make docker-verify` runs the health, random-verse, and no-CDN checks against a running\ninstance.\n\n**Upgrading from an older Concord?** Rebuild the database. The geography tables (v3) are now\npart of the required schema, so a `bible.db` built before v3 fails fast at startup with a\nrebuild hint — `make build-db`, or just rebuild the image, which bakes a fresh one. A clean\n`docker compose up --build` needs no thought here; only a hand-carried older database does.\n\n## Security\n\nConcord is built for a **trusted LAN**: read-only, no authentication, no writes, and no\ninternet access at runtime. It runs as a non-root user, opens its database read-only, caps\nrequest input sizes, and sets `X-Content-Type-Options: nosniff`. CORS is intentionally open\n(`*`) with credentials disabled — correct for an unauthenticated, read-only service on a\ntrusted network.\n\nThe compute-heavy `/v1/semantic-search` is protected by two in-process bounds, each shedding\noverload with `503` + `Retry-After`: a concurrency cap on how *many* inferences run at once\n(`CONCORD_SEMANTIC_MAX_CONCURRENCY`, default 2) and a wall-clock deadline on how *long* a\nsingle one may run (`CONCORD_SEMANTIC_TIMEOUT_S`, default 10s). The deadline bounds caller\nwait, not CPU (a slow inference runs to completion and keeps its slot), so on slow (non-AVX2)\nhardware you should **still set a client / reverse-proxy read-timeout** as defense-in-depth\n(see [`docs/SECURITY.md`](docs/SECURITY.md)).\n\n**It is not hardened for the public internet.** Before exposing it beyond a LAN, put a\nreverse proxy (TLS), authentication, and rate limiting in front of it. The full threat model\nand the checklist for public exposure are in [`docs/SECURITY.md`](docs/SECURITY.md).\n\n## The data\n\nConcord bundles **13 public-domain English translations** (KJV, WEB, ASV, YLT, BSB, and others\n— see `GET /v1/translations` for the full list), each with its own public-domain notice, plus the\noriginal-language texts — the **SBL Greek New Testament** (`?translation=SBLGNT`) and the **Hebrew\nOld Testament** (`?translation=OSHB`, right-to-left). Full provenance is in\n[`data/SOURCES.md`](data/SOURCES.md).\n\nCross-references come from the OpenBible.info dataset (344,799 of them):\n\n\u003e Cross-reference data courtesy of [OpenBible.info](https://www.openbible.info/labs/cross-references/), licensed under a Creative Commons Attribution (CC BY) license.\n\nPlace coordinates and the place↔verse links come from OpenBible.info's Bible-Geocoding dataset\n(1,340 places):\n\n\u003e Place data courtesy of [OpenBible.info](https://github.com/openbibleinfo/Bible-Geocoding-Data), licensed under a Creative Commons Attribution 4.0 International (CC BY 4.0) license.\n\nTopical browsing comes from Nave's Topical Bible (Orville J. Nave, 1897 — public domain),\nvia a machine-readable compilation (5,319 topics):\n\n\u003e Topical data from Nave's Topical Bible (public domain; 1897), via [BradyStephenson/bible-data](https://github.com/BradyStephenson/bible-data), licensed under a Creative Commons Attribution 4.0 International (CC BY 4.0) license.\n\nThe original-language texts and the Strong's lexicons come from STEPBible — the Greek NT (`SBLGNT`,\n7,917 verses, the SBL-edition word selection) from the Amalgamated Greek NT, and the Hebrew OT\n(`OSHB`, 23,145 verses) from the Amalgamated Hebrew OT (Westminster Leningrad Codex tradition,\nloaded under English/NRSV verse numbers, right-to-left):\n\n\u003e Original-language and lexicon data created by [STEPBible.org](https://github.com/STEPBible/STEPBible-Data) based on work at Tyndale House Cambridge, licensed under a Creative Commons Attribution 4.0 International (CC BY 4.0) license; the SBLGNT is © 2010 Society of Biblical Literature \u0026 Logos Bible Software, CC BY 4.0.\n\nSome translations aren't public-domain and can't be redistributed. Concord supports them\nthrough a gitignored `data/private/` directory: drop a non-distributable translation's JSON\nthere and the loader picks it up automatically on a local build, while it never enters the\npublic repo or a shared image. The pattern lets an operator run translations they're licensed\nfor without ever committing them.\n\nSemantic search uses IBM's\n[`granite-embedding-311m-multilingual-r2`](https://huggingface.co/ibm-granite/granite-embedding-311m-multilingual-r2)\nembedding model — **Apache 2.0 licensed**, pinned to a fixed revision and baked into the\nimage (the int8 build, ~313 MB). It's downloaded once at build time and never contacted at\nruntime.\n\n## What Concord doesn't do (yet)\n\nConcord is deliberately scoped. Semantic search landed in v2, geography in v3, and a curated\njourneys layer in v7; a few things still haven't made a release, on purpose:\n\n- **Competing routes for the journeys.** The curated journeys (Paul's missionary journeys, the\n  Exodus) shipped in v7 as **one commonly proposed reconstruction each** — ordered sequences of\n  existing places, reusing v3's geography rather than rebuilding it. What's deliberately *not*\n  modeled is the **competing routes** scholars propose, route variants, and segment-level dating —\n  a distinct research problem, deferred to its own future layer.\n- **Catholic and deuterocanonical books.** The schema is ready for them, but the data, naming\n  conventions, and Vulgate psalm-numbering mapping are all distinct work that didn't belong in\n  a clean release. Future work.\n- **Notes semantic search.** Keyword search over translator's notes shipped in v5\n  (`GET /v1/notes/search`); *meaning-based* search over them is designed but gated behind real\n  demand — the note-embedding corpus is large and tied to restrictively-licensed source text, so\n  it's opt-in/local rather than something every instance pays for. Keyword notes search covers the\n  common case.\n- **Multi-translation *semantic* search.** Not a gap — it's deliberately not a thing. Semantic\n  search is already translation-agnostic: it ranks verse *references* in one meaning-space (WEB) and\n  renders them in whatever translation you ask for, so \"search all translations\" has no meaning for\n  it. (Keyword multi-translation search *did* ship in v5 — see `GET /v1/search?translations=`.)\n- **Ship translator's notes.** The notes endpoint\n  (`GET /v1/translations/{translation}/notes/{book}/{chapter}`) is fully wired and live, but\n  the public image ships **zero** notes — the richest source (NET) is copyrighted, and notes\n  are user-supplied by design. So on a stock image this endpoint returns `200` with an empty\n  list for every translation. To populate it, bake your own legally-obtained notes in via the\n  gitignored `data/private/notes/` directory — see\n  [`docs/API.md`](docs/API.md#get-v1translationstranslationnotesbookchapter) and\n  [`examples/notes-sample.json`](examples/notes-sample.json) for the file shape.\n\nIf any of these would unblock a project of yours, open an issue and say so — it shapes what\ngets built next.\n\n## Building on Concord\n\nConcord exists to be built on — and a small but growing ecosystem already runs on it:\n\n- **The app it's for:** [songbird](https://github.com/kbennett2000/songbird) is a polished\n  end-user Bible app built on top of Concord — a working desktop client of this `/v1` surface.\n- **Use it from your AI assistant:** [concord-mcp](https://github.com/kbennett2000/concord-mcp)\n  is an MCP server that hands Concord's verse lookup, semantic search, cross-references,\n  original-language word study, and place data to an AI assistant as tools — so Claude answers\n  from verses it actually looked up in your instance, quoted with a verifiable reference like\n  `John 3:16 (KJV)`, instead of reciting them from memory.\n- **Embedding in-process:** because `bible-core` has no web dependencies, a Python project can\n  import it directly and query Scripture without running the HTTP server at all.\n  [`examples/embed_in_process.py`](examples/embed_in_process.py) is a runnable example — it\n  parses a reference and fetches a verse with no server running, then (if the embedding model\n  and vector store are present) does a `bible-semantic` query in-process too.\n- **Learn to build on it — three courses, from \"what's an API?\" to reading a real AI codebase:**\n  **[concord-tutorial-web](https://github.com/kbennett2000/concord-tutorial-web)** builds your\n  first real app in plain HTML and JavaScript (no experience needed), and\n  **[concord-tutorial-react](https://github.com/kbennett2000/concord-tutorial-react)** picks up\n  from there into React — ending with you reading songbird's own source and finding you can…and\n  **[concord-tutorial-ai](https://github.com/kbennett2000/concord-tutorial-ai)** adds local AI\n  tool-calling in plain JavaScript — ending with the student reading concord-mcp's source at\n  v1.0.0 and recognizing every part.\n\nThe `/v1` prefix means today's responses are a contract. Build against them with confidence.\n\n## License \u0026 attribution\n\n- **Code:** MIT © 2026 Kris Bennett — see [`LICENSE`](LICENSE).\n- **Bundled translations:** the 13 English translations are public domain — see\n  [`data/SOURCES.md`](data/SOURCES.md).\n- **Original-language texts (SBLGNT, OSHB):** [STEPBible-Data](https://github.com/STEPBible/STEPBible-Data)\n  (Tyndale House Cambridge), licensed under Creative Commons Attribution 4.0 International\n  (CC BY 4.0); the SBLGNT is © 2010 Society of Biblical Literature \u0026 Logos Bible Software; the\n  Hebrew descends from the OpenScriptures / Westminster Leningrad Codex text.\n- **Strong's lexicons (Greek + Hebrew):** [STEPBible-Data](https://github.com/STEPBible/STEPBible-Data)\n  (Tyndale House Cambridge; the Brief lexicons draw on Abbott-Smith for Greek and BDB for Hebrew),\n  licensed under Creative Commons Attribution 4.0 International (CC BY 4.0). The Strong's numbering\n  (1890) is public domain.\n- **Cross-references:** [OpenBible.info](https://www.openbible.info/labs/cross-references/),\n  licensed under Creative Commons Attribution (CC BY).\n- **Place data:** [OpenBible.info Bible-Geocoding-Data](https://github.com/openbibleinfo/Bible-Geocoding-Data),\n  licensed under Creative Commons Attribution 4.0 International (CC BY 4.0).\n- **Topical data:** Nave's Topical Bible (public domain; 1897), via\n  [BradyStephenson/bible-data](https://github.com/BradyStephenson/bible-data),\n  licensed under Creative Commons Attribution 4.0 International (CC BY 4.0).\n- **Embedding model:** [`ibm-granite/granite-embedding-311m-multilingual-r2`](https://huggingface.co/ibm-granite/granite-embedding-311m-multilingual-r2),\n  Apache 2.0 © IBM.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkbennett2000%2Fconcord","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkbennett2000%2Fconcord","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkbennett2000%2Fconcord/lists"}