Local-first CLI for multi-dimensional document analysis: semantic search, geographic extraction, temporal annotation, and NER — all stored in SQLite, exportable to GeoJSON, KML, and TIMEX formats.
cd akb
pip install -e ".[llm]"
python -m spacy download en_core_web_smmacOS 26 (Tahoe) + Intel Mac: uv doesn't yet map
macosx_26_0_x86_64tomacosx_11_0_x86_64wheels. Usepipinstead ofuv pip, or prefix uv commands withMACOSX_DEPLOYMENT_TARGET=11.0. This is a uv bug;pipworks without any workaround.
# Ingest documents
akb ingest https://example.com/paper.pdf
akb ingest path/to/document.md
# Process pipeline
akb chunk --all --strategy markdown
akb embed --all
akb ner --all
akb resolve geo --all
akb resolve chrono --all
# Search
akb search "water harvesting agricultural yield"
akb search "Lake Chad climate displacement" --llm
# Export
akb export geo --all --format geojson --out map.geojson
akb export chrono --all --format timex-json --out timeline.json
akb export entities --all --type LOC --format csv --out locations.csv
# UI + MCP server (http://localhost:8765)
akb serveakb exposes its corpus as GeoAgent tools, letting you query the knowledge base in natural language and render results on a live Leaflet map — with optional overlay of STAC / NASA OPERA satellite data.
pip install -e ".[llm,geoagent]"Open notebooks/geoagent_demo.ipynb. Run the quickstart pipeline first if you haven't
already (see notebook header), then work through three sections:
Section 1 — Direct tool calls (no GeoAgent install required)
Call the four akb tools directly and load results into leafmap:
from cli.geoagent_tools import akb_search_locations, akb_get_timeline_locations
geojson = akb_search_locations("water harvesting flood mitigation", top_k=12)
m = leafmap.Map(center=[12, 10], zoom=5)
m.add_geojson(geojson, layer_name="Search results")
mSection 2 — Full GeoAgent session
Create an agent bound to a live map. It autonomously decides which akb tools to
call, adds GeoJSON layers to the map, and answers in prose:
from cli.geoagent_tools import make_agent
import leafmap
m = leafmap.Map(center=[12, 10], zoom=5)
agent = make_agent(map=m, model="claude-sonnet-4-6")
resp = agent.chat("Find climate displacement sites in northeast Nigeria and add them to the map.")
show(resp) # pretty-prints the answer as Markdown with tools-used footerThe agent has the full built-in leafmap tool suite (add/remove/list layers, zoom, basemap switching, STAC search) alongside the akb corpus tools.
Section 3 — Export for external GIS
Dump the full geocoded corpus or a filtered subset to GeoJSON for QGIS / Google Earth:
full = akb_export_geojson()
pathlib.Path("corpus.geojson").write_text(json.dumps(full, indent=2))| Tool | Description |
|---|---|
akb_search_locations |
Hybrid BM25 + semantic search → GeoJSON of matching LOC spans |
akb_get_timeline_locations |
Filter all geocoded locations by ISO date window |
akb_get_entity_network |
All corpus knowledge about a named place: co-entities, time refs, excerpts |
akb_export_geojson |
Full corpus export, optionally filtered by document title |
# Call a tool directly — output is GeoJSON on stdout
akb geoagent --tool search-locations --query "Lake Chad climate"
akb geoagent --tool timeline-locations --start 0900 --end 1500 --out medieval.geojson
akb geoagent --tool entity-network --query "Maiduguri"
akb geoagent --tool export-geojson --out corpus.geojson
# Full agent prompt (requires geoagent install)
akb geoagent "Show water management sites from 900–1500 CE"| Tool | How |
|---|---|
| Google Earth | akb export geo --format kml → drag KML into Google Earth |
| QGIS / any GIS | akb export geo --format geojson → import as vector layer |
| TIMEX viewers (brat) | akb export chrono --format timex3-xml |
| QMD | Point QMD collection at akb/data/blocks/ |
| Claude Code | akb serve → add MCP endpoint http://localhost:8765/.well-known/mcp.json |
| Observable / Jupyter | Query akb/data/archive.db directly with SQL |
| GeoAgent / leafmap | pip install -e ".[geoagent]" — see section above |
blocks — one per source document (+ .md file in data/blocks/)
chunks — text segments with embeddings, linked prev/next
ner_spans — LOC, TIME, PERSON, ORG, KEYWORD with geo/chrono resolution
processing_runs — provenance: model + config used for each processing step
kb-viz/ is a full-stack visualizer for the akb corpus. The Python adapter
(kb_viz/akb_adapter.py) converts an akb SQLite database into a manifest JSON
that the React frontend reads.
# Generate manifest from your database
python -m kb_viz.akb_adapter data/archive.db -o kb-viz/frontend/public/manifest.json
# Start the visualizer
cd kb-viz/frontend && npm install && npm run dev
# → http://localhost:5173| Frame | What you see |
|---|---|
| Semantic | UMAP embedding cloud. Toggle 2D / 3D (drag-rotatable OrbitView). |
| Map | Geographic scatter on dark tiles. Heatmap, great-circle arcs, convex hull of selection. |
| Timeline | Temporal scatter. Drag to brush a date range — filters all frames. |
| Chart | Position × length scatter with axis ticks. |
| Graph | Force-directed node graph with edge-type toggles. |
| Text | Selected node's text with inline geo/temporal/entity highlights. |
Layout is fully flexible: drag to split/resize panes, save named presets, add/maximize frames.
See kb-viz/README.md for the full guide and changelog.
# From parent repo
git submodule add https://github.com/suruleredotdev/akb akb
git submodule update --init