An offline-first spatio-temporal database engine and map visualization server written in Go.
Cronotopia ingests and indexes data from Wikidata and Wikipedia, stores vector map tiles, and includes a native neural inference engine for vector embeddings. All records, full-text indices, geospatial R*Trees, vector embeddings, ANN index clusters, GGUF model weights, and map tiles are stored in a single SQLite database file.
Cronotopia is built to query historical events and geographic data without external services or internet access. It combines historical entity extraction, full-text article sections, and an integrated vector tile server.
The system includes a pure Go execution engine for quantized GGUF embedding models. This enables semantic and hybrid search locally on CPU without any dependencies. In addition to a web frontend and REST API, Cronotopia implements a Model Context Protocol (MCP) server for integration with AI tools and agents.
- 100% Offline: Operates with no network dependencies once the database is populated. No external database engines or runtime libraries required.
- Single-File Storage: Entities, coordinates, timestamps, article sections (FTS5), spatial R*Trees, vector embeddings, ANN clusters, GGUF weights, and map tiles live in one SQLite file.
- Data Ingestion:
- Wikidata: Stream ingestion of large dumps (
.json,.gz,.bz2) extracting temporal events, geographic coordinates, and entity links. - Wikipedia: Ingestion of Wikipedia Enterprise HTML dumps (
tar.gz) parsed into structured sections with an FTS5 index. - MBTiles: Direct import of Mapbox vector tiles (
.mbtiles) into the internal tile schema. - GGUF Models: Direct import of the model weights into SQLite for local embedding generation.
- Wikilite: One-step import of existing Wikilite SQLite databases.
- Wikidata: Stream ingestion of large dumps (
- Embedded AI & Semantic Search:
- Native Go implementation of Qwen3 transformer inference for Q8_0 quantization on CPU.
- Configurable between low-RAM layer-by-layer reading and cached RAM execution.
- Approximate Nearest Neighbor (ANN) index generation using Matryoshka Representation Learning (MRL) dimension reduction.
- Hybrid retrieval combining BM25 full-text scoring, vector cosine distance, and spatio-temporal filters.
- Optional support for external embedding APIs.
- Spatio-Temporal Queries: Fast spatial bounding-box checks using SQLite R*Tree, Haversine distance calculations, and Julian day calendar conversions for historical dates (exact date, before, after).
- Tile Server & Web UI: Serves vector tiles (PBF/MVT) directly to an embedded MapLibre GL frontend.
- MCP Server: Native
/mcpendpoint exposing tools over JSON-RPC 2.0 (POST) and Server-Sent Events (GET).
Pre-compiled standalone binaries for Linux, macOS, and Windows are available on the Releases page.
To run Cronotopia without processing raw dumps, download a prebuilt database containing historical entities, articles, embeddings, and vector tiles from Hugging Face.
Requires Go 1.22 or later:
git clone https://github.com/eja/cronotopia.git
cd cronotopia
go build -o cronotopia .Cronotopia runs in import mode, server mode, or both. If any import or synchronization flag is specified, the application completes the tasks before starting the web server.
./cronotopia --db cronotopia.db --import-mbtiles ./planet.mbtiles./cronotopia --db cronotopia.db \
--import-wikidata ./wikidata-latest-all.json.gz./cronotopia --db cronotopia.db \
--import-wikipedia ./enwiki-enterprise-html.tar.gz./cronotopia --db cronotopia.db \
--import-gguf ./qwen3-embedding-0.6b-q8_0.ggufGenerate embeddings for imported sections:
./cronotopia --db cronotopia.db --ai-sync \
--ai-api --ai-api-url "http://localhost:8080/v1/embeddings" \
--ai-model "Qwen3-Embedding-0.6B-Q8_0"./cronotopia --db cronotopia.db --import-wikilite ./wikilite-en.dbStart the web server, tile server, REST API, and MCP endpoint:
./cronotopia --db cronotopia.db --web-host 0.0.0.0 --web-port 35248The MapLibre interface will be available at http://localhost:35248.
| Flag | Default | Description |
|---|---|---|
--db |
cronotopia.db |
SQLite database file path. |
--web-host |
0.0.0.0 |
Server listen host. |
--web-port |
35248 |
Server listen port. |
--language |
en |
Comma-separated ISO language codes. |
--limit |
20 |
Default search result limit. |
--import-wikidata |
"" |
Path or URL to Wikidata dump (.json, .gz, .bz2). |
--import-wikipedia |
"" |
Path or URL to Wikipedia Enterprise HTML dump (.tar.gz). |
--import-wikilite |
"" |
Path to a pre-indexed Wikilite database. |
--import-mbtiles |
"" |
Path to an MBTiles file. |
--import-gguf |
"" |
Path to a GGUF model file. |
--ai-sync |
false |
Generate vector embeddings for unindexed sections. |
--ai-ann |
true |
Build clustered Matryoshka ANN index during embedding sync. |
--ai-ann-size |
64 |
Dimension size for MRL vector indexing. |
--ai-cache |
false |
Cache model weights in memory. |
--ai-api |
false |
Use an external HTTP API for embeddings. |
--ai-api-url |
http://localhost:8080/v1/embeddings |
Embeddings API endpoint. |
--ai-api-key |
"" |
Bearer key for embeddings API. |
--ai-model |
Qwen3-Embedding-0.6B-Q8_0 |
Model name string. |
--ai-model-prefix-search |
Instruct: Retrieve... |
Prompt prefix added to search queries. |
--ai-model-prefix-save |
"" |
Prompt prefix added to passage text. |
--log |
true |
Enable logging. |
--log-file |
"" |
File path for log output. |
Queries records by text, semantic vector, location, or time.
Parameters:
| Parameter | Type | Description |
|---|---|---|
query |
string | Search text. |
mode |
string | hybrid (default), lexical (FTS5 BM25), or semantic (vector similarity). |
latitude |
float | Target latitude for spatial search. |
longitude |
float | Target longitude for spatial search. |
radius_km |
float | Search radius in kilometers (default: 100). |
year |
int | Astronomical year (negative numbers for BCE). |
month |
int | Month (1-12). |
day |
int | Day (1-31). |
range |
string/int | Date matching: 0 (exact), -1 or lt (before), 1 or gt (after). |
limit |
int | Maximum results returned (default: 20). |
language |
string | Language code override. |
Examples:
# Events near Rome in 44 BCE
curl "http://localhost:35248/api?latitude=41.9028&longitude=12.4964&radius_km=25&year=-44"
# Hybrid text and geographic search
curl "http://localhost:35248/api?query=Renaissance+artists&latitude=43.7696&longitude=11.2558"
# Vector semantic search
curl "http://localhost:35248/api?query=ancient+naval+warfare&mode=semantic"Retrieves Wikipedia sections, coordinates, and dates for an entity.
Parameters:
id: Entity ID (e.g.8467for Q8467) or Wikipedia article ID.entity_id: Filter by Wikidata entity ID.article_id: Filter by Wikipedia article ID.
curl "http://localhost:35248/api/article?id=8467"GET /api/map: Returns center coordinates and zoom levels from settings.GET /tiles/{z}/{x}/{y}.pbf: Serves vector tiles directly from SQLite.
Cronotopia provides an MCP endpoint at /mcp supporting JSON-RPC 2.0 over HTTP POST and SSE streams over GET.
search_events- Locate events by coordinates, radius, and year.
- Arguments:
latitude(number),longitude(number),radius_km(number),year(integer),limit(integer).
search_knowledge- Query indexed text and article sections.
- Arguments:
query(string),limit(integer).
get_article- Fetch full article text and section headings.
- Arguments:
id(integer).
- Wikidata: Source for entities, coordinates, dates, and claims.
- Wikipedia: Source for encyclopedic text and article structure.
- OpenStreetMap: Geospatial data source for map tiles.
- Qwen Team: Base embedding model architecture.
- MapLibre: Client-side vector map renderer.
- SQLite: Embedded storage engine.