Graph-based biblical and religious text study platform
Project description
Exegia Backend
Graph-based biblical and religious text study API — powered by Context-Fabric, FastAPI, Strawberry GraphQL, and FastMCP.
What is this?
Exegia is a backend for studying annotated religious texts (Bible, Quran, Tanakh, commentaries, lexicons). It exposes corpus data through two surfaces:
| Surface | Technology | Use case |
|---|---|---|
| GraphQL API | Strawberry + FastAPI | Frontend apps, structured queries |
| MCP server | FastMCP | AI assistants (Claude, GPT, etc.) |
Corpora are loaded from Context-Fabric — a graph-based annotated text engine. Every word, verse, chapter, and book is a typed node in a graph with queryable features (lemma, morphology, gloss, etc.).
Architecture
┌─────────────────────────────────────────────────────────────┐
│ Clients │
│ Frontend │ AI Assistant │ CLI / Script │
└────────┬───────────┴────────┬──────────┴────────┬───────────┘
│ │ │
GraphQL (Strawberry) MCP (FastMCP) REST (FastAPI)
│ │ │
┌────────▼────────────────────▼───────────────────▼───────────┐
│ exegia package │
│ .graphql │ .mcp │ .corpus │ .utils │
└───────────────────────────┬─────────────────────────────────┘
│
┌────────────────▼────────────────┐
│ Context-Fabric (cfabric) │
│ F · E · L · T · S · N · C │
└────────────────┬────────────────┘
│
┌────────────────▼────────────────┐
│ corpus datasets │
│ ~/.exegia/datasets/... │
└─────────────────────────────────┘
Package modules
Everything lives in the exegia namespace (src/exegia/):
| Module | Purpose |
|---|---|
exegia.mcp |
FastMCP server — 11 corpus tools for AI clients |
exegia.graphql |
Strawberry GraphQL schema over corpus data |
exegia.corpus |
Fetch TF datasets from git repositories |
exegia.utils |
EPUB / HTML → Text-Fabric converters |
exegia.models |
Shared enums and data model definitions |
exegia.schemas |
Pydantic request/response schemas |
exegia.auth |
Auth utilities |
Tech stack
- Python 3.13+ with uv for dependency management
- FastAPI — HTTP framework
- Strawberry GraphQL — schema-first GraphQL with full type safety
- FastMCP 2 — MCP server for AI clients
- Context-Fabric (
cfabric) — graph corpus engine (fork of Text-Fabric)
Getting started
Prerequisites
- uv ≥ 0.9
- Python 3.13
Install
git clone <repo-url>
cd backend
uv run scripts/setup.py
Environment
cp .env.example .env
# fill in any required environment variables
Run the API
uv run uvicorn main:app --reload
GraphQL API
The schema exposes a corpus hierarchy: Corpus → Book → Chapter → Verse → Word.
Endpoint: POST /graphql
Example queries
# Fetch a passage
query {
passage(corpus: "BHSA", reference: "Genesis 1:1-3") {
reference
text
words {
text
lemma
partOfSpeech
gloss
}
}
}
# Morphological word search
query {
words(corpus: "BHSA", filter: { book: "Genesis", partOfSpeech: "verb", verbTense: "perfect" }, limit: 50) {
text
lemma
gloss
}
}
# Raw Context-Fabric pattern search
query {
search(corpus: "BHSA", pattern: "word pos=verb\n book name=Genesis") {
reference
text
}
}
GraphQL types
| Type | Key fields |
|---|---|
Corpus |
name, nodeTypes, featureCount, books |
Book |
name, chapters |
Chapter |
reference, verses |
Verse |
reference, text, words |
Word |
text, lemma, partOfSpeech, gloss, gender, number, person, verbStem, verbTense, feature(name) |
SearchMatch |
reference, text |
Field names use natural language (lemma, partOfSpeech) instead of raw corpus shorthand (lex, sp). Use the feature(name) escape hatch to access any raw feature directly.
MCP server
The MCP server lets AI assistants query corpora directly via the Model Context Protocol.
Start the server
# stdio — for Claude Desktop and other MCP clients
uv run cf-mcp --corpus ~/.exegia/datasets/bibles/BHSA
# SSE on port 8000 — for remote / desktop app connections
uv run cf-mcp --corpus ~/.exegia/datasets/bibles/BHSA --sse 8000
# Multiple corpora at once
uv run cf-mcp \
--corpus ~/.exegia/datasets/bibles/BHSA --name BHSA \
--corpus ~/.exegia/datasets/bibles/GNT --name GNT
Available tools (11)
| Category | Tool | Description |
|---|---|---|
| Discovery | list_corpora |
List loaded corpora and the active one |
| Discovery | describe_corpus |
Node types with counts, section hierarchy |
| Discovery | list_features |
Browse features, filter by node type |
| Discovery | describe_feature |
Metadata + top values by frequency |
| Discovery | get_text_formats |
Available text encodings with samples |
| Search | search |
Pattern search — results / count / statistics / passages |
| Search | search_continue |
Paginate large result sets via cursor |
| Search | search_csv |
Export results to a local CSV file |
| Search | search_syntax_guide |
Inline query syntax documentation |
| Data | get_passages |
Retrieve text by section reference |
| Data | get_node_features |
Batch feature lookup for a list of nodes |
Recommended workflow for AI agents
describe_corpus() → understand what node types exist
list_features() → see what annotations are available
search_syntax_guide() → learn the query language
search(template, "count") → check scale before fetching results
search(template, "results") → get paginated result set
get_passages(references) → read the matched text
Programmatic use
from exegia.mcp import mcp, corpus_manager
corpus_manager.load("~/.exegia/datasets/bibles/BHSA", name="BHSA")
mcp.run(transport="sse", host="localhost", port=8000)
Corpus datasets
Datasets are Text-Fabric archives extracted locally under ~/.exegia/datasets/.
Fetch from git
from exegia.corpus.fetch_from_git import fetch_datasets_from_git
paths = fetch_datasets_from_git("https://github.com/ETCBC/bhsa")
# returns list[Path] of dirs containing otext.tf + otype.tf
Importing books (EPUB / HTML)
Books can be converted from EPUB or HTML into Text-Fabric datasets for corpus querying.
from exegia.utils.convert_epub_to_tf import convert_epub_to_tf
tf_path = convert_epub_to_tf(
epub_path="commentary.epub",
output_dir="~/.exegia/datasets/books/my-commentary/",
corpus_name="MyCommentary",
)
The converter produces this node hierarchy:
book
chapter (EPUB spine item / page)
element (block HTML element)
paragraph (paragraph-like elements)
word (slot — smallest unit)
The output directory is a valid TF dataset, loadable by the MCP server or GraphQL API immediately:
uv run cf-mcp --corpus ~/.exegia/datasets/books/my-commentary
Development
Run tests
uv run pytest
Build the wheel
uv build --out-dir dist/
Publish
uv run scripts/publish.py # bump patch, commit, tag, push
uv run scripts/publish.py minor # bump minor
uv run scripts/publish.py 1.2.3 # explicit version
Project layout
backend/
├── pyproject.toml # Package config (hatchling build)
├── uv.lock
├── scripts/
│ ├── setup.py # Install deps + dotenvx
│ ├── clean.py # Remove caches and build artifacts
│ ├── stop.py # Stop local uvicorn processes
│ ├── publish.py # Build + publish helper
│ └── work.py # Git workflow helper
├── .github/
│ └── workflows/
│ └── publish.yml # CI: build + publish on tag push
└── src/
└── exegia/
├── auth/ # Auth utilities
├── corpus/ # Git dataset fetching
├── graphql/ # Strawberry GraphQL schema
├── mcp/ # FastMCP server (cf-mcp entrypoint)
├── models/ # Enums and data model definitions
├── schemas/ # Pydantic API schemas
└── utils/ # EPUB/HTML → TF converters
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file py_exegia-0.1.11.tar.gz.
File metadata
- Download URL: py_exegia-0.1.11.tar.gz
- Upload date:
- Size: 189.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cb7a6af2341ba3a1ae7ba2a7775245ae8972e6be97736e3d99da43ddfad1c3a0
|
|
| MD5 |
c385411afbad50c8301fdf77003cb45b
|
|
| BLAKE2b-256 |
7b147e2efbe324fe393a92b59dbf6b911742cd9635368aecf969c326dff138f2
|
File details
Details for the file py_exegia-0.1.11-py3-none-any.whl.
File metadata
- Download URL: py_exegia-0.1.11-py3-none-any.whl
- Upload date:
- Size: 42.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eeb72ead84f1cc3570e7f7c0241925ae3385ab30642cf32938937eb9080d3e91
|
|
| MD5 |
ad0cfbdbfdce3bdeecf5e35d690aa9e8
|
|
| BLAKE2b-256 |
14c9f95aebb68c0426942882218691bead6736376c928b0eccaf93c72bba1323
|