LibreJyotish
Deterministic Vedic astrology calculations as an MCP server
Open-source and free. Sidereal positions, houses, dashas and panchang, computed from Swiss Ephemeris.
30-second quickstart
Add to Claude Desktop — Settings → Developer → Edit Config → claude_desktop_config.json:
{
"mcpServers": {
"librejyotish": {
"command": "uvx",
"args": ["librejyotish"]
}
}
}
Restart Claude — a tools icon (hammer/wrench) appears at the bottom of the chat input. Click it to confirm the server's tools are loaded. Then head to Example prompts for things to try.
Example prompts
Once the tools are connected, paste any of these straight into Claude. Each one resolves through the server’s tools:
✨ Natal reading.
“I was born 1994-03-21 14:32 in Nashik, India. Tell me my Lagna, nakshatra, D9, and current Mahadasha — and what they mean in plain language.”
💞 Love & compatibility.
“How compatible are me and my partner? I’m born 1988-06-14 09:20 in New York, they’re born 1991-11-02 18:45 in London. Compare our Moons, D9 charts, and current dashas for marriage, communication, and long-term fit.”
📅 Auspicious-timing screening.
“I’m picking a date to launch. Give me the next three auspicious windows this year from the panchang.”
🌑 Eclipse hitting your Moon.
“Show me the eclipse that will land on my natal Moon, and when.”
💪 Strength of a planet.
“Where in my chart is Saturn strongest for me as a writer?”
⏳ Life-arc timing.
“Walk me through the big timing cycles in my life for the next 20 years.”
Conventions
Reported in every response’s conventions_used block so you know exactly what was assumed:
- Zodiac: sidereal, Lahiri (Chitrapaksha) ayanamsha by default
- Houses: whole-sign from the Lagna sign
- Dasha: Vimshottari
- Nodes: true by default
- Positions: apparent by default
- Varas, tithis, etc.: sunrise-anchored civil day
Tools
| Tool | Input | Output |
|---|---|---|
get_natal_chart |
birth datetime + location | ascendant, planets with sign/nakshatra/house, retrograde & combustion flags, dignities |
get_divisional_chart |
+ division (D1–D60) |
varga sign & house per body (Parashara rules incl. classical Trimshamsha) |
get_vimshottari_dasha |
birth input (+ optional reference moment) | mahadasha → antardasha → pratyantardasha tree, current chain annotated |
get_panchang |
date + location | tithi, vara, nakshatra/pada, yoga, karana, sunrise/sunset |
get_ashtakavarga |
birth input | Bhinnashtakavarga per planet (with prastara), Sarvashtakavarga totals |
get_shadbala |
birth input | six-fold strength: sthana, dig, kala, cheshta, naisargika, drik; virupas/rupas vs required |
get_current_transits |
birth input + optional as-of moment | transit positions with house from natal Lagna and natal Moon (raw positions only) |
get_eclipses |
birth input + optional as-of moment + count |
next solar/lunar eclipses: exact event times, type, eclipse point (sidereal sign/nakshatra) and its house from natal Lagna & Moon |
geocode_location |
place string + optional country |
offline gazetteer lookup → latitude/longitude/IANA-timezone candidates (use the top hit’s numbers as the latitude/longitude inputs above) |
batch |
list of {tool, arguments} |
run many charts/panchang/geocodes in one call — result per op, order preserved, one failure never discards the rest |
All tools are stateless: JSON in, structured dict out. Errors are {"error": {"type", "message"}}. Every response includes an explicit conventions_used block.
batch is the answer to "can't I just loop client-side?": a 20-chart comparison costs one model round-trip instead of 20, and a single bad input fails as an error entry without discarding the other 19 results — so you keep the deterministic server-side shared state (ephemeris files, gazetteer, ayanamsha resolution) and avoid N round trips of your own.
Defensive by default
The server greets a sketchy input with a warning rather than a silently wrong chart. It flags an internally inconsistent date/time/location (e.g. a timezone that doesn't match the coordinates, or coordinates that resolve to a place 500+ km away, producing a sunset before sunrise) and tells you exactly what to fix. Use the top geocode_location candidate's numbers and strip stray guesses — the tools will catch the rest.
Limitations
- Gazetteer covers cities ≥ 20k population.
geocode_locationresolves against a generously-sourced but deliberately-shipped-down GeoNames subset, so obscure small towns and villages won't resolve — and in this domain a lot of birthplaces are villages. If an exact hit isn't found, the tool reportsresolved: falsewith the searched string echoed back; treat that as "resolve the coordinates yourself and pass them directly" rather than a bug. - Ephemeris spans 1800–2399 (the bundled Swiss Ephemeris
sepl_18.se1/semo_18.se1files). Births outside that range fall back to the built-in Moshier model, which is reported inephemeris_source.
Setup alternatives
Install the CLI directly (any machine):
uvx librejyotish --version # prints 0.1.1
uvx librejyotish # runs the MCP server over stdio
# or install permanently:
uv tool install librejyotish
librejyotish --version
How the uvx install works. uvx fetches the wheel from PyPI once and runs isolated; the wheel bundles Swiss Ephemeris sepl_18.se1/semo_18.se1 (1800–2399, AGPL) and GeoNames cities.csv (CC-BY), so startup is instant and offline — no separate download step, no network at query time.
A full first-claude query resolves through geocode_location → get_natal_chart → get_divisional_chart(D9) → get_vimshottari_dasha, and the assistant answers in plain language, citing conventions_used.
From source (development):
conda env create -f environment.yml # or your own venv with the two deps
conda run -n librejyotish python -m librejyotish.server # or python server.py (shim)
# after pip install -e .:
pip install -e .
librejyotish --version
librejyotish
Ephemeris and gazetteer live in librejyotish/data/ inside the wheel under AGPL (Swiss Ephemeris dual-licensed AGPL/commercial; this project distributes the .se1 files under AGPL). If files are absent, the server falls back to the built-in Moshier model and warns loudly, reporting the source in ephemeris_source.
To rebuild the gazetteer or refresh .se1 files:
conda run -n librejyotish python scripts/build_gazetteer.py
conda run -n librejyotish python scripts/download_ephe.py # refreshes librejyotish/data/ephe/
MCP client config — from source / conda:
{
"mcpServers": {
"librejyotish": {
"command": "conda",
"args": ["run", "-n", "librejyotish", "python", "-m", "librejyotish.server"]
}
}
}
Legacy python /path/to/server.py still works via a shim at the repo root.
Validation
scripts/crosscheck_*.pycompare every module against PyJHora as an independent oracle (dev-only). All vargas, dasha boundaries, panchang elements, Ashtakavarga tables, and the exactly-comparable Shadbala components match; known PyJHora defects in paksha/dig/cheshta/hora/ayana handling follow canon instead (see module docstrings).tests/reference_charts/fixtures.jsonpins four reference charts (1947, 1994, 2000, 2026 Delhi);pytestreplays them end-to-end:
conda run -n librejyotish python -m pytest tests/ -q
Acknowledgments
- Swiss Ephemeris — Astrodienst / pyswisseph: the astronomical engine behind every calculation.
- PyJHora — naturalstupid/PyJHora: independent reference used to validate the Vedic math (dev-only, not imported in production).
- GeoNames — GeoNames: city data powering the offline
geocode_locationgazetteer.
License
AGPL-3.0-or-later. Swiss Ephemeris is AGPL/commercial dual-licensed; this project uses it under the AGPL and carries the license forward. Hosting the MCP server as a network service triggers AGPL’s network clause (source disclosure to users of the service).
Data attributions: Swiss Ephemeris .se1 files © Astrodienst / Alois Treindl (AGPL); GeoNames cities.csv © GeoNames (CC BY 4.0) — see librejyotish/data/gazetteer/README.md.
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 librejyotish-0.1.1.tar.gz.
File metadata
- Download URL: librejyotish-0.1.1.tar.gz
- Upload date:
- Size: 7.7 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.11.16
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f79d1ddec8367ee0dc2c94c779e41c44cf771791c610c4b0571f2134b02d24e1
|
|
| MD5 |
ab03f098c3613375a538fd51991a67f7
|
|
| BLAKE2b-256 |
5d207b8dcd16df76c1cb1b3bfc77d33a109be829f71887220a4e3b22391ecf71
|
File details
Details for the file librejyotish-0.1.1-py3-none-any.whl.
File metadata
- Download URL: librejyotish-0.1.1-py3-none-any.whl
- Upload date:
- Size: 4.2 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.11.16
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ae2a5675baccb496ccafc6a29c0ee50c5f6f93d62b337dd6f4ef91916717a55f
|
|
| MD5 |
f4045b67c1dc2669d9e64a4715211821
|
|
| BLAKE2b-256 |
6e48667369eb1f1b85d163fc04a414e7d3992980de705c851f2de5fb3089dd00
|