# caelus Caelus is a clean-room, MIT-licensed TypeScript suite for validated astrology computation. It computes ephemeris positions, charts, events, hellenistic timing techniques, Vedic methods, citable chart facts, sky-view image-prompt frames, and MCP tools. The core engine has zero dependencies and zero I/O (data injected). It computes apparent geocentric positions for sun, moon, mercury..pluto, chiron, mean_node, true_node (+ mean_lilith, true_lilith, ceres, pallas, juno, vesta, pholus, cupido, hades, zeus, kronos, apollon, admetos, vulkanus, poseidon on request); speeds, retrograde flags, ecliptic lat, distance (AU), RA/Dec; tropical or sidereal zodiac (lahiri, fagan_bradley, krishnamurti, raman, yukteshwar, galcent_0sag, true_citra); topocentric option; ASC/MC/vertex/east point; 12 house systems (placidus, porphyry, equal, whole_sign, koch, regiomontanus, campanus, alcabitius, morinus, meridian, polich_page, vehlow); major aspects; pheno (phase, elongation, diameter, magnitude), equation of time, az/alt, refraction; 319 fixed stars (HYG catalog); Gauquelin sectors; SkyView (project the visible sky to image-canvas pixels for AI image prompts: per-body placement, apparent size, magnitude-to-brightness cues, Moon phase orientation, twilight and limiting magnitude, Bortle dark-sky class, a deep 8,920-star field, the Milky Way band, ecliptic/sign/house/constellation overlays, the celestial pole, and time sequences for animation); synthetic ephemeris (imaginary bodies with placement, periodic, and Kepler motion — register on Engine for returns, transits, and SkyView with authored render attrs); event search (rise/set/meridian transits, zodiac crossings, lunar phases, stations, solar/lunar eclipses). Higher layers: derived charts (returns, progressions, solar arc, composite, Davison, harmonics, antiscia, draconic, declination aspects, dignities, sect), electional primitives (applying/separating, combustion/cazimi, planetary hours, void-of-course Moon, house placement), the when() declarative query engine, the turbo longitude tier, and scan/rankMoments ranked time search, the 3D great-circle aspect (angularSeparation3d), astrocartography angle lines, ephemeris time series, a chart feature space with configuration search (chart-to-vector, cosine similarity, searchConfigurations), and a geometric compiler that inverts geometric constraints to a chart form and flags impossible ones. engine.chart(year,month,day,hour,min,sec,lat,lonEast,opts) takes calendar fields in UT (not a Julian Day); engine.chartAt(jdUt,lat,lonEast,opts) builds the same chart directly from a Julian Day. Supported range 1000-3000 on the embedded/modern packs (validated vs JPL Horizons; the embedded npm Moon tier is 1920-2080, analytic series outside). The Node loader's classical era slabs extend the Sun, Moon, Mercury, Venus, Mars, Jupiter, and Saturn to −2998–3000. Verified per-body vs Swiss Ephemeris over the modern era, vs JPL over the wide span: Sun-Saturn <=1", Uranus <=1.9", Neptune <=4.6", Moon <=2.5", Pluto <=3.4" (Chebyshev pack), Chiron <=1", mean node <=1", true node <= 1' vs SE's built-in ephemeris, mean lilith <=1.6", the 8 new house systems exact; sidereal adds <=0.005". TS engine pinned to a Python reference by 3,440 golden checks (worst diff 0.61e-9 arcsec). Repo: https://github.com/heavyblotto/caelus ## Install - caelus@0.25.0 — the engine - caelus-birth@0.25.0 — local birth time + place -> UT (use this; see below) - caelus-wheel@0.25.0 — React SVG chart wheel, plus MultiWheel (up to four rings), ChartSphere (3D), AstroMap (astrocartography), EphemerisGraph (band/marks/cursor) - caelus-mcp@0.25.0 — MCP server, 35 chart tools over stdio (natal_chart, current_sky, transits, synastry, parans, find_aspect_dates, sky_events, sky_view, sky_view_sequence, synthetic_validate, synthetic_positions, synthetic_sky_view, rectification_grid, planetary_hours, void_of_course, returns, progressions, composite, dignities, lots, profections, firdaria, releasing, directions, nakshatras, dasha, vargas, yogas, aspect_patterns, chart_signature, similar_skies, electional_search, cosmic_weather, chart_facts, counterfactual_chart); also hosted over MCP Streamable HTTP (stateless) at https://www.ephemengine.com/api/mcp; listed on the official MCP Registry as io.github.heavyblotto/caelus-mcp - caelus-delineations-pd@0.1.6 — public-domain interpretation corpus (372 cited passages) for interpret(); sources and publicDomainSources - caelus-engine (PyPI) — the Python reference engine (no numpy), https://pypi.org/project/caelus-engine/ Interpretation layer: interpretationContext() -> ranked citable fact atoms across 27 kinds (placements, aspects, patterns, signature, angles and planets on them, dispositors, receptions, stars, lots, degree, transits by aspect and by house, stations, returns in progress, lunations and eclipses in the natal houses, solar phase, synastry, composite and composite aspects, time-lords, fine dignities, nakshatra/varga/yoga, parallels, out-of-bounds); enrichContextOptions() / enrichSynastryOptions() wire the diachronic and two-chart layers; chartBrief() + auditCitations() for LLM grounding. Playground readings use unpublished caelus-corpus; caelus-delineations-pd remains the published npm reference. Docs: https://www.ephemengine.com/docs/interpretation ## Entry points - `caelus` — Engine, BODIES, julianDay, mod, fmtLon, types - `caelus/data-embedded` — bundled coefficient data (~153 KB gz), browser/edge - `caelus/node` — loadNodeData(dir, vsopTier, moonTier) fs loader, Node only ```ts import { Engine } from "caelus"; import { embeddedData } from "caelus/data-embedded"; const engine = new Engine(embeddedData); const chart = engine.chart(1990, 6, 10, 18, 30, 0, 27.95, -82.46, "placidus"); // options form: house system, sidereal zodiac, extra bodies, topocentric const sid = engine.chart(1990, 6, 10, 18, 30, 0, 27.95, -82.46, { houseSystem: "koch", zodiac: "sidereal:lahiri", bodies: ["mean_lilith"] }); ``` ## THE INPUT IS UT — not local time `engine.chart(...)` takes UT date/time components. Converting a user's local birth time with `new Date(localString)` uses the RUNTIME's timezone and silently produces charts wrong by hours. Use caelus-birth: ```ts import { toUT } from "caelus-birth"; const t = toUT({ year: 1990, month: 6, day: 10, hour: 14, minute: 30, lat: 27.95, lon: -82.46 }); // local clock time + place // t.utc -> UT components for engine.chart(); t.status flags DST edge cases ``` Longitude is EAST-positive everywhere (Americas are negative). ## Chart object shape ```ts { jdUt: number, houseSystem, houseSystemRequested, // differ when Placidus falls back // to whole_sign above polar circles zodiac, // "tropical" | "sidereal:" bodies: { [body]: { lon, speed, retrograde, sign, signDeg, lat, dist, ra, dec } }, // degrees; dist in AU angles: { asc, mc, vertex, eastPoint }, cusps: number[12], aspects: [{ a, b, aspect, orb }], } ``` ## More - Validation tables: https://ephemengine.com/validation - Data provenance: https://ephemengine.com/provenance - Hosted MCP endpoint (Streamable HTTP): https://www.ephemengine.com/api/mcp - Pitfalls for coding agents: docs/agents.md in the repo - MCP spec: MCP_SPEC.md in the repo