caelus-mcp 0.13.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -3
- package/dist/src/server.d.ts +585 -1
- package/dist/src/server.js +276 -8
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
# caelus-mcp
|
|
2
2
|
|
|
3
3
|
MCP server for the [caelus](https://github.com/heavyblotto/caelus) ephemeris
|
|
4
|
-
engine:
|
|
4
|
+
engine: twenty-two chart tools over stdio. Computation only — positions, houses,
|
|
5
5
|
aspects with orbs, event search, electional, returns, progressions, composite,
|
|
6
6
|
dignities, Hermetic lots, the Hellenistic time-lords (profections, firdaria,
|
|
7
|
-
zodiacal releasing),
|
|
7
|
+
zodiacal releasing), primary directions, and the Vedic layer (nakshatras,
|
|
8
|
+
dashas, vargas, yogas) — the model does the interpreting.
|
|
8
9
|
It needs
|
|
9
10
|
no API keys, ephemeris files, or network calls; the engine data ships inside
|
|
10
11
|
the package.
|
|
@@ -55,7 +56,11 @@ A hosted Streamable HTTP endpoint is also live at
|
|
|
55
56
|
| `profections` | Annual and monthly profections to a target date: age, the profected signs and their whole-sign houses, and the lord of the year |
|
|
56
57
|
| `firdaria` | The firdaria planetary time-lord periods: the full 75-year timeline (nine periods, seven sub-periods each) and the lords active at a target date |
|
|
57
58
|
| `releasing` | Zodiacal releasing (aphesis) from the Lot of Spirit or Fortune: the L1–L4 period timeline and the lords active at a target date, with loosing of the bond |
|
|
58
|
-
| `directions` | Primary directions of the seven traditional planets to the four angles (MC/IC/Asc/Desc) by the Naibod or Ptolemy time key, sorted by age |
|
|
59
|
+
| `directions` | Primary directions of the seven traditional planets to the four angles (MC/IC/Asc/Desc), and optionally between the planets (mundane), by the Naibod or Ptolemy time key, sorted by age |
|
|
60
|
+
| `nakshatras` | The nakshatra (lunar mansion), pada, and ruling planet of each classical planet and the Ascendant on the sidereal zodiac (Lahiri by default) |
|
|
61
|
+
| `dasha` | Vedic dasha periods from the Moon's nakshatra — Vimshottari (120y), Yogini (36y), or Ashtottari (108y): the maha → antar timeline and the lords active at a target date |
|
|
62
|
+
| `vargas` | Parashari divisional charts (D1 rasi, D2, D3, D9 navamsa, D10, D12, D30): the divisional sign of each planet and the Ascendant |
|
|
63
|
+
| `yogas` | Vedic yogas on the rasi chart: Pancha Mahapurusha, Gajakesari, Budha-Aditya, Chandra-Mangala, Kemadruma, plus raja/dhana yogas and yogakarakas |
|
|
59
64
|
|
|
60
65
|
`natal_chart` and `current_sky` also tag each body with its solar phase
|
|
61
66
|
(cazimi/combust/under-the-beams) and each aspect with applying/separating.
|
package/dist/src/server.d.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* caelus-mcp -- MCP server for the caelus ephemeris engine.
|
|
4
4
|
*
|
|
5
5
|
* Design (per 2026 MCP practice): one bounded context (chart computation),
|
|
6
|
-
* a small curated tool surface (
|
|
6
|
+
* a small curated tool surface (twenty-two outcome-level tools, not API wrappers),
|
|
7
7
|
* and token-frugal outputs (positions to 0.01 deg, terse keys, no prose --
|
|
8
8
|
* the model does the interpreting, the server does the math).
|
|
9
9
|
*
|
|
@@ -1591,6 +1591,25 @@ export declare const directionsOut: z.ZodObject<{
|
|
|
1591
1591
|
angle: "MC" | "IC" | "ASC" | "DSC";
|
|
1592
1592
|
arc: number;
|
|
1593
1593
|
}>, "many">;
|
|
1594
|
+
mundane: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
1595
|
+
promissor: z.ZodString;
|
|
1596
|
+
significator: z.ZodString;
|
|
1597
|
+
arc: z.ZodNumber;
|
|
1598
|
+
years: z.ZodNumber;
|
|
1599
|
+
date: z.ZodString;
|
|
1600
|
+
}, "strip", z.ZodTypeAny, {
|
|
1601
|
+
date: string;
|
|
1602
|
+
years: number;
|
|
1603
|
+
arc: number;
|
|
1604
|
+
promissor: string;
|
|
1605
|
+
significator: string;
|
|
1606
|
+
}, {
|
|
1607
|
+
date: string;
|
|
1608
|
+
years: number;
|
|
1609
|
+
arc: number;
|
|
1610
|
+
promissor: string;
|
|
1611
|
+
significator: string;
|
|
1612
|
+
}>, "many">>;
|
|
1594
1613
|
}, "strip", z.ZodTypeAny, {
|
|
1595
1614
|
natal_utc: string;
|
|
1596
1615
|
key: "ptolemy" | "naibod";
|
|
@@ -1601,6 +1620,13 @@ export declare const directionsOut: z.ZodObject<{
|
|
|
1601
1620
|
angle: "MC" | "IC" | "ASC" | "DSC";
|
|
1602
1621
|
arc: number;
|
|
1603
1622
|
}[];
|
|
1623
|
+
mundane?: {
|
|
1624
|
+
date: string;
|
|
1625
|
+
years: number;
|
|
1626
|
+
arc: number;
|
|
1627
|
+
promissor: string;
|
|
1628
|
+
significator: string;
|
|
1629
|
+
}[] | undefined;
|
|
1604
1630
|
}, {
|
|
1605
1631
|
natal_utc: string;
|
|
1606
1632
|
key: "ptolemy" | "naibod";
|
|
@@ -1611,6 +1637,272 @@ export declare const directionsOut: z.ZodObject<{
|
|
|
1611
1637
|
angle: "MC" | "IC" | "ASC" | "DSC";
|
|
1612
1638
|
arc: number;
|
|
1613
1639
|
}[];
|
|
1640
|
+
mundane?: {
|
|
1641
|
+
date: string;
|
|
1642
|
+
years: number;
|
|
1643
|
+
arc: number;
|
|
1644
|
+
promissor: string;
|
|
1645
|
+
significator: string;
|
|
1646
|
+
}[] | undefined;
|
|
1647
|
+
}>;
|
|
1648
|
+
export declare const nakshatrasOut: z.ZodObject<{
|
|
1649
|
+
natal_utc: z.ZodString;
|
|
1650
|
+
zodiac: z.ZodEnum<["tropical", "sidereal:lahiri", "sidereal:fagan_bradley", "sidereal:krishnamurti", "sidereal:raman", "sidereal:yukteshwar", "sidereal:galcent_0sag", "sidereal:true_citra"]>;
|
|
1651
|
+
points: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
1652
|
+
nakshatra: z.ZodString;
|
|
1653
|
+
pada: z.ZodNumber;
|
|
1654
|
+
lord: z.ZodString;
|
|
1655
|
+
deg: z.ZodNumber;
|
|
1656
|
+
}, "strip", z.ZodTypeAny, {
|
|
1657
|
+
deg: number;
|
|
1658
|
+
lord: string;
|
|
1659
|
+
nakshatra: string;
|
|
1660
|
+
pada: number;
|
|
1661
|
+
}, {
|
|
1662
|
+
deg: number;
|
|
1663
|
+
lord: string;
|
|
1664
|
+
nakshatra: string;
|
|
1665
|
+
pada: number;
|
|
1666
|
+
}>>;
|
|
1667
|
+
}, "strip", z.ZodTypeAny, {
|
|
1668
|
+
zodiac: "tropical" | "sidereal:lahiri" | "sidereal:fagan_bradley" | "sidereal:krishnamurti" | "sidereal:raman" | "sidereal:yukteshwar" | "sidereal:galcent_0sag" | "sidereal:true_citra";
|
|
1669
|
+
natal_utc: string;
|
|
1670
|
+
points: Record<string, {
|
|
1671
|
+
deg: number;
|
|
1672
|
+
lord: string;
|
|
1673
|
+
nakshatra: string;
|
|
1674
|
+
pada: number;
|
|
1675
|
+
}>;
|
|
1676
|
+
}, {
|
|
1677
|
+
zodiac: "tropical" | "sidereal:lahiri" | "sidereal:fagan_bradley" | "sidereal:krishnamurti" | "sidereal:raman" | "sidereal:yukteshwar" | "sidereal:galcent_0sag" | "sidereal:true_citra";
|
|
1678
|
+
natal_utc: string;
|
|
1679
|
+
points: Record<string, {
|
|
1680
|
+
deg: number;
|
|
1681
|
+
lord: string;
|
|
1682
|
+
nakshatra: string;
|
|
1683
|
+
pada: number;
|
|
1684
|
+
}>;
|
|
1685
|
+
}>;
|
|
1686
|
+
export declare const dashaOut: z.ZodObject<{
|
|
1687
|
+
natal_utc: z.ZodString;
|
|
1688
|
+
system: z.ZodEnum<["vimshottari", "yogini", "ashtottari"]>;
|
|
1689
|
+
moon_nakshatra: z.ZodString;
|
|
1690
|
+
start_lord: z.ZodOptional<z.ZodString>;
|
|
1691
|
+
start_yogini: z.ZodOptional<z.ZodString>;
|
|
1692
|
+
balance_years: z.ZodNumber;
|
|
1693
|
+
periods: z.ZodArray<z.ZodObject<{
|
|
1694
|
+
lord: z.ZodOptional<z.ZodString>;
|
|
1695
|
+
yogini: z.ZodOptional<z.ZodString>;
|
|
1696
|
+
start: z.ZodString;
|
|
1697
|
+
end: z.ZodString;
|
|
1698
|
+
sub: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
1699
|
+
lord: z.ZodOptional<z.ZodString>;
|
|
1700
|
+
yogini: z.ZodOptional<z.ZodString>;
|
|
1701
|
+
start: z.ZodString;
|
|
1702
|
+
end: z.ZodString;
|
|
1703
|
+
}, "strip", z.ZodTypeAny, {
|
|
1704
|
+
start: string;
|
|
1705
|
+
end: string;
|
|
1706
|
+
lord?: string | undefined;
|
|
1707
|
+
yogini?: string | undefined;
|
|
1708
|
+
}, {
|
|
1709
|
+
start: string;
|
|
1710
|
+
end: string;
|
|
1711
|
+
lord?: string | undefined;
|
|
1712
|
+
yogini?: string | undefined;
|
|
1713
|
+
}>, "many">>;
|
|
1714
|
+
}, "strip", z.ZodTypeAny, {
|
|
1715
|
+
start: string;
|
|
1716
|
+
end: string;
|
|
1717
|
+
lord?: string | undefined;
|
|
1718
|
+
sub?: {
|
|
1719
|
+
start: string;
|
|
1720
|
+
end: string;
|
|
1721
|
+
lord?: string | undefined;
|
|
1722
|
+
yogini?: string | undefined;
|
|
1723
|
+
}[] | undefined;
|
|
1724
|
+
yogini?: string | undefined;
|
|
1725
|
+
}, {
|
|
1726
|
+
start: string;
|
|
1727
|
+
end: string;
|
|
1728
|
+
lord?: string | undefined;
|
|
1729
|
+
sub?: {
|
|
1730
|
+
start: string;
|
|
1731
|
+
end: string;
|
|
1732
|
+
lord?: string | undefined;
|
|
1733
|
+
yogini?: string | undefined;
|
|
1734
|
+
}[] | undefined;
|
|
1735
|
+
yogini?: string | undefined;
|
|
1736
|
+
}>, "many">;
|
|
1737
|
+
active: z.ZodOptional<z.ZodObject<{
|
|
1738
|
+
target_utc: z.ZodString;
|
|
1739
|
+
maha: z.ZodNullable<z.ZodString>;
|
|
1740
|
+
antar: z.ZodNullable<z.ZodString>;
|
|
1741
|
+
pratyantar: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
1742
|
+
}, "strip", z.ZodTypeAny, {
|
|
1743
|
+
target_utc: string;
|
|
1744
|
+
maha: string | null;
|
|
1745
|
+
antar: string | null;
|
|
1746
|
+
pratyantar?: string | null | undefined;
|
|
1747
|
+
}, {
|
|
1748
|
+
target_utc: string;
|
|
1749
|
+
maha: string | null;
|
|
1750
|
+
antar: string | null;
|
|
1751
|
+
pratyantar?: string | null | undefined;
|
|
1752
|
+
}>>;
|
|
1753
|
+
}, "strip", z.ZodTypeAny, {
|
|
1754
|
+
natal_utc: string;
|
|
1755
|
+
periods: {
|
|
1756
|
+
start: string;
|
|
1757
|
+
end: string;
|
|
1758
|
+
lord?: string | undefined;
|
|
1759
|
+
sub?: {
|
|
1760
|
+
start: string;
|
|
1761
|
+
end: string;
|
|
1762
|
+
lord?: string | undefined;
|
|
1763
|
+
yogini?: string | undefined;
|
|
1764
|
+
}[] | undefined;
|
|
1765
|
+
yogini?: string | undefined;
|
|
1766
|
+
}[];
|
|
1767
|
+
system: "yogini" | "vimshottari" | "ashtottari";
|
|
1768
|
+
moon_nakshatra: string;
|
|
1769
|
+
balance_years: number;
|
|
1770
|
+
active?: {
|
|
1771
|
+
target_utc: string;
|
|
1772
|
+
maha: string | null;
|
|
1773
|
+
antar: string | null;
|
|
1774
|
+
pratyantar?: string | null | undefined;
|
|
1775
|
+
} | undefined;
|
|
1776
|
+
start_lord?: string | undefined;
|
|
1777
|
+
start_yogini?: string | undefined;
|
|
1778
|
+
}, {
|
|
1779
|
+
natal_utc: string;
|
|
1780
|
+
periods: {
|
|
1781
|
+
start: string;
|
|
1782
|
+
end: string;
|
|
1783
|
+
lord?: string | undefined;
|
|
1784
|
+
sub?: {
|
|
1785
|
+
start: string;
|
|
1786
|
+
end: string;
|
|
1787
|
+
lord?: string | undefined;
|
|
1788
|
+
yogini?: string | undefined;
|
|
1789
|
+
}[] | undefined;
|
|
1790
|
+
yogini?: string | undefined;
|
|
1791
|
+
}[];
|
|
1792
|
+
system: "yogini" | "vimshottari" | "ashtottari";
|
|
1793
|
+
moon_nakshatra: string;
|
|
1794
|
+
balance_years: number;
|
|
1795
|
+
active?: {
|
|
1796
|
+
target_utc: string;
|
|
1797
|
+
maha: string | null;
|
|
1798
|
+
antar: string | null;
|
|
1799
|
+
pratyantar?: string | null | undefined;
|
|
1800
|
+
} | undefined;
|
|
1801
|
+
start_lord?: string | undefined;
|
|
1802
|
+
start_yogini?: string | undefined;
|
|
1803
|
+
}>;
|
|
1804
|
+
export declare const vargasOut: z.ZodObject<{
|
|
1805
|
+
natal_utc: z.ZodString;
|
|
1806
|
+
zodiac: z.ZodEnum<["tropical", "sidereal:lahiri", "sidereal:fagan_bradley", "sidereal:krishnamurti", "sidereal:raman", "sidereal:yukteshwar", "sidereal:galcent_0sag", "sidereal:true_citra"]>;
|
|
1807
|
+
charts: z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
1808
|
+
sign: z.ZodString;
|
|
1809
|
+
sign_index: z.ZodNumber;
|
|
1810
|
+
division: z.ZodNumber;
|
|
1811
|
+
}, "strip", z.ZodTypeAny, {
|
|
1812
|
+
sign: string;
|
|
1813
|
+
sign_index: number;
|
|
1814
|
+
division: number;
|
|
1815
|
+
}, {
|
|
1816
|
+
sign: string;
|
|
1817
|
+
sign_index: number;
|
|
1818
|
+
division: number;
|
|
1819
|
+
}>>>;
|
|
1820
|
+
}, "strip", z.ZodTypeAny, {
|
|
1821
|
+
zodiac: "tropical" | "sidereal:lahiri" | "sidereal:fagan_bradley" | "sidereal:krishnamurti" | "sidereal:raman" | "sidereal:yukteshwar" | "sidereal:galcent_0sag" | "sidereal:true_citra";
|
|
1822
|
+
natal_utc: string;
|
|
1823
|
+
charts: Record<string, Record<string, {
|
|
1824
|
+
sign: string;
|
|
1825
|
+
sign_index: number;
|
|
1826
|
+
division: number;
|
|
1827
|
+
}>>;
|
|
1828
|
+
}, {
|
|
1829
|
+
zodiac: "tropical" | "sidereal:lahiri" | "sidereal:fagan_bradley" | "sidereal:krishnamurti" | "sidereal:raman" | "sidereal:yukteshwar" | "sidereal:galcent_0sag" | "sidereal:true_citra";
|
|
1830
|
+
natal_utc: string;
|
|
1831
|
+
charts: Record<string, Record<string, {
|
|
1832
|
+
sign: string;
|
|
1833
|
+
sign_index: number;
|
|
1834
|
+
division: number;
|
|
1835
|
+
}>>;
|
|
1836
|
+
}>;
|
|
1837
|
+
export declare const yogasOut: z.ZodObject<{
|
|
1838
|
+
natal_utc: z.ZodString;
|
|
1839
|
+
zodiac: z.ZodEnum<["tropical", "sidereal:lahiri", "sidereal:fagan_bradley", "sidereal:krishnamurti", "sidereal:raman", "sidereal:yukteshwar", "sidereal:galcent_0sag", "sidereal:true_citra"]>;
|
|
1840
|
+
yogas: z.ZodArray<z.ZodObject<{
|
|
1841
|
+
yoga: z.ZodString;
|
|
1842
|
+
planets: z.ZodArray<z.ZodString, "many">;
|
|
1843
|
+
}, "strip", z.ZodTypeAny, {
|
|
1844
|
+
yoga: string;
|
|
1845
|
+
planets: string[];
|
|
1846
|
+
}, {
|
|
1847
|
+
yoga: string;
|
|
1848
|
+
planets: string[];
|
|
1849
|
+
}>, "many">;
|
|
1850
|
+
kemadruma: z.ZodBoolean;
|
|
1851
|
+
raja_yogas: z.ZodArray<z.ZodObject<{
|
|
1852
|
+
lords: z.ZodArray<z.ZodString, "many">;
|
|
1853
|
+
via: z.ZodString;
|
|
1854
|
+
}, "strip", z.ZodTypeAny, {
|
|
1855
|
+
lords: string[];
|
|
1856
|
+
via: string;
|
|
1857
|
+
}, {
|
|
1858
|
+
lords: string[];
|
|
1859
|
+
via: string;
|
|
1860
|
+
}>, "many">;
|
|
1861
|
+
dhana_yogas: z.ZodArray<z.ZodObject<{
|
|
1862
|
+
lords: z.ZodArray<z.ZodString, "many">;
|
|
1863
|
+
via: z.ZodString;
|
|
1864
|
+
}, "strip", z.ZodTypeAny, {
|
|
1865
|
+
lords: string[];
|
|
1866
|
+
via: string;
|
|
1867
|
+
}, {
|
|
1868
|
+
lords: string[];
|
|
1869
|
+
via: string;
|
|
1870
|
+
}>, "many">;
|
|
1871
|
+
yogakarakas: z.ZodArray<z.ZodString, "many">;
|
|
1872
|
+
}, "strip", z.ZodTypeAny, {
|
|
1873
|
+
zodiac: "tropical" | "sidereal:lahiri" | "sidereal:fagan_bradley" | "sidereal:krishnamurti" | "sidereal:raman" | "sidereal:yukteshwar" | "sidereal:galcent_0sag" | "sidereal:true_citra";
|
|
1874
|
+
natal_utc: string;
|
|
1875
|
+
yogas: {
|
|
1876
|
+
yoga: string;
|
|
1877
|
+
planets: string[];
|
|
1878
|
+
}[];
|
|
1879
|
+
kemadruma: boolean;
|
|
1880
|
+
raja_yogas: {
|
|
1881
|
+
lords: string[];
|
|
1882
|
+
via: string;
|
|
1883
|
+
}[];
|
|
1884
|
+
dhana_yogas: {
|
|
1885
|
+
lords: string[];
|
|
1886
|
+
via: string;
|
|
1887
|
+
}[];
|
|
1888
|
+
yogakarakas: string[];
|
|
1889
|
+
}, {
|
|
1890
|
+
zodiac: "tropical" | "sidereal:lahiri" | "sidereal:fagan_bradley" | "sidereal:krishnamurti" | "sidereal:raman" | "sidereal:yukteshwar" | "sidereal:galcent_0sag" | "sidereal:true_citra";
|
|
1891
|
+
natal_utc: string;
|
|
1892
|
+
yogas: {
|
|
1893
|
+
yoga: string;
|
|
1894
|
+
planets: string[];
|
|
1895
|
+
}[];
|
|
1896
|
+
kemadruma: boolean;
|
|
1897
|
+
raja_yogas: {
|
|
1898
|
+
lords: string[];
|
|
1899
|
+
via: string;
|
|
1900
|
+
}[];
|
|
1901
|
+
dhana_yogas: {
|
|
1902
|
+
lords: string[];
|
|
1903
|
+
via: string;
|
|
1904
|
+
}[];
|
|
1905
|
+
yogakarakas: string[];
|
|
1614
1906
|
}>;
|
|
1615
1907
|
export declare const OUTPUT_SCHEMAS: {
|
|
1616
1908
|
readonly natal_chart: z.ZodObject<{
|
|
@@ -3312,6 +3604,25 @@ export declare const OUTPUT_SCHEMAS: {
|
|
|
3312
3604
|
angle: "MC" | "IC" | "ASC" | "DSC";
|
|
3313
3605
|
arc: number;
|
|
3314
3606
|
}>, "many">;
|
|
3607
|
+
mundane: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
3608
|
+
promissor: z.ZodString;
|
|
3609
|
+
significator: z.ZodString;
|
|
3610
|
+
arc: z.ZodNumber;
|
|
3611
|
+
years: z.ZodNumber;
|
|
3612
|
+
date: z.ZodString;
|
|
3613
|
+
}, "strip", z.ZodTypeAny, {
|
|
3614
|
+
date: string;
|
|
3615
|
+
years: number;
|
|
3616
|
+
arc: number;
|
|
3617
|
+
promissor: string;
|
|
3618
|
+
significator: string;
|
|
3619
|
+
}, {
|
|
3620
|
+
date: string;
|
|
3621
|
+
years: number;
|
|
3622
|
+
arc: number;
|
|
3623
|
+
promissor: string;
|
|
3624
|
+
significator: string;
|
|
3625
|
+
}>, "many">>;
|
|
3315
3626
|
}, "strip", z.ZodTypeAny, {
|
|
3316
3627
|
natal_utc: string;
|
|
3317
3628
|
key: "ptolemy" | "naibod";
|
|
@@ -3322,6 +3633,13 @@ export declare const OUTPUT_SCHEMAS: {
|
|
|
3322
3633
|
angle: "MC" | "IC" | "ASC" | "DSC";
|
|
3323
3634
|
arc: number;
|
|
3324
3635
|
}[];
|
|
3636
|
+
mundane?: {
|
|
3637
|
+
date: string;
|
|
3638
|
+
years: number;
|
|
3639
|
+
arc: number;
|
|
3640
|
+
promissor: string;
|
|
3641
|
+
significator: string;
|
|
3642
|
+
}[] | undefined;
|
|
3325
3643
|
}, {
|
|
3326
3644
|
natal_utc: string;
|
|
3327
3645
|
key: "ptolemy" | "naibod";
|
|
@@ -3332,6 +3650,272 @@ export declare const OUTPUT_SCHEMAS: {
|
|
|
3332
3650
|
angle: "MC" | "IC" | "ASC" | "DSC";
|
|
3333
3651
|
arc: number;
|
|
3334
3652
|
}[];
|
|
3653
|
+
mundane?: {
|
|
3654
|
+
date: string;
|
|
3655
|
+
years: number;
|
|
3656
|
+
arc: number;
|
|
3657
|
+
promissor: string;
|
|
3658
|
+
significator: string;
|
|
3659
|
+
}[] | undefined;
|
|
3660
|
+
}>;
|
|
3661
|
+
readonly nakshatras: z.ZodObject<{
|
|
3662
|
+
natal_utc: z.ZodString;
|
|
3663
|
+
zodiac: z.ZodEnum<["tropical", "sidereal:lahiri", "sidereal:fagan_bradley", "sidereal:krishnamurti", "sidereal:raman", "sidereal:yukteshwar", "sidereal:galcent_0sag", "sidereal:true_citra"]>;
|
|
3664
|
+
points: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
3665
|
+
nakshatra: z.ZodString;
|
|
3666
|
+
pada: z.ZodNumber;
|
|
3667
|
+
lord: z.ZodString;
|
|
3668
|
+
deg: z.ZodNumber;
|
|
3669
|
+
}, "strip", z.ZodTypeAny, {
|
|
3670
|
+
deg: number;
|
|
3671
|
+
lord: string;
|
|
3672
|
+
nakshatra: string;
|
|
3673
|
+
pada: number;
|
|
3674
|
+
}, {
|
|
3675
|
+
deg: number;
|
|
3676
|
+
lord: string;
|
|
3677
|
+
nakshatra: string;
|
|
3678
|
+
pada: number;
|
|
3679
|
+
}>>;
|
|
3680
|
+
}, "strip", z.ZodTypeAny, {
|
|
3681
|
+
zodiac: "tropical" | "sidereal:lahiri" | "sidereal:fagan_bradley" | "sidereal:krishnamurti" | "sidereal:raman" | "sidereal:yukteshwar" | "sidereal:galcent_0sag" | "sidereal:true_citra";
|
|
3682
|
+
natal_utc: string;
|
|
3683
|
+
points: Record<string, {
|
|
3684
|
+
deg: number;
|
|
3685
|
+
lord: string;
|
|
3686
|
+
nakshatra: string;
|
|
3687
|
+
pada: number;
|
|
3688
|
+
}>;
|
|
3689
|
+
}, {
|
|
3690
|
+
zodiac: "tropical" | "sidereal:lahiri" | "sidereal:fagan_bradley" | "sidereal:krishnamurti" | "sidereal:raman" | "sidereal:yukteshwar" | "sidereal:galcent_0sag" | "sidereal:true_citra";
|
|
3691
|
+
natal_utc: string;
|
|
3692
|
+
points: Record<string, {
|
|
3693
|
+
deg: number;
|
|
3694
|
+
lord: string;
|
|
3695
|
+
nakshatra: string;
|
|
3696
|
+
pada: number;
|
|
3697
|
+
}>;
|
|
3698
|
+
}>;
|
|
3699
|
+
readonly dasha: z.ZodObject<{
|
|
3700
|
+
natal_utc: z.ZodString;
|
|
3701
|
+
system: z.ZodEnum<["vimshottari", "yogini", "ashtottari"]>;
|
|
3702
|
+
moon_nakshatra: z.ZodString;
|
|
3703
|
+
start_lord: z.ZodOptional<z.ZodString>;
|
|
3704
|
+
start_yogini: z.ZodOptional<z.ZodString>;
|
|
3705
|
+
balance_years: z.ZodNumber;
|
|
3706
|
+
periods: z.ZodArray<z.ZodObject<{
|
|
3707
|
+
lord: z.ZodOptional<z.ZodString>;
|
|
3708
|
+
yogini: z.ZodOptional<z.ZodString>;
|
|
3709
|
+
start: z.ZodString;
|
|
3710
|
+
end: z.ZodString;
|
|
3711
|
+
sub: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
3712
|
+
lord: z.ZodOptional<z.ZodString>;
|
|
3713
|
+
yogini: z.ZodOptional<z.ZodString>;
|
|
3714
|
+
start: z.ZodString;
|
|
3715
|
+
end: z.ZodString;
|
|
3716
|
+
}, "strip", z.ZodTypeAny, {
|
|
3717
|
+
start: string;
|
|
3718
|
+
end: string;
|
|
3719
|
+
lord?: string | undefined;
|
|
3720
|
+
yogini?: string | undefined;
|
|
3721
|
+
}, {
|
|
3722
|
+
start: string;
|
|
3723
|
+
end: string;
|
|
3724
|
+
lord?: string | undefined;
|
|
3725
|
+
yogini?: string | undefined;
|
|
3726
|
+
}>, "many">>;
|
|
3727
|
+
}, "strip", z.ZodTypeAny, {
|
|
3728
|
+
start: string;
|
|
3729
|
+
end: string;
|
|
3730
|
+
lord?: string | undefined;
|
|
3731
|
+
sub?: {
|
|
3732
|
+
start: string;
|
|
3733
|
+
end: string;
|
|
3734
|
+
lord?: string | undefined;
|
|
3735
|
+
yogini?: string | undefined;
|
|
3736
|
+
}[] | undefined;
|
|
3737
|
+
yogini?: string | undefined;
|
|
3738
|
+
}, {
|
|
3739
|
+
start: string;
|
|
3740
|
+
end: string;
|
|
3741
|
+
lord?: string | undefined;
|
|
3742
|
+
sub?: {
|
|
3743
|
+
start: string;
|
|
3744
|
+
end: string;
|
|
3745
|
+
lord?: string | undefined;
|
|
3746
|
+
yogini?: string | undefined;
|
|
3747
|
+
}[] | undefined;
|
|
3748
|
+
yogini?: string | undefined;
|
|
3749
|
+
}>, "many">;
|
|
3750
|
+
active: z.ZodOptional<z.ZodObject<{
|
|
3751
|
+
target_utc: z.ZodString;
|
|
3752
|
+
maha: z.ZodNullable<z.ZodString>;
|
|
3753
|
+
antar: z.ZodNullable<z.ZodString>;
|
|
3754
|
+
pratyantar: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
3755
|
+
}, "strip", z.ZodTypeAny, {
|
|
3756
|
+
target_utc: string;
|
|
3757
|
+
maha: string | null;
|
|
3758
|
+
antar: string | null;
|
|
3759
|
+
pratyantar?: string | null | undefined;
|
|
3760
|
+
}, {
|
|
3761
|
+
target_utc: string;
|
|
3762
|
+
maha: string | null;
|
|
3763
|
+
antar: string | null;
|
|
3764
|
+
pratyantar?: string | null | undefined;
|
|
3765
|
+
}>>;
|
|
3766
|
+
}, "strip", z.ZodTypeAny, {
|
|
3767
|
+
natal_utc: string;
|
|
3768
|
+
periods: {
|
|
3769
|
+
start: string;
|
|
3770
|
+
end: string;
|
|
3771
|
+
lord?: string | undefined;
|
|
3772
|
+
sub?: {
|
|
3773
|
+
start: string;
|
|
3774
|
+
end: string;
|
|
3775
|
+
lord?: string | undefined;
|
|
3776
|
+
yogini?: string | undefined;
|
|
3777
|
+
}[] | undefined;
|
|
3778
|
+
yogini?: string | undefined;
|
|
3779
|
+
}[];
|
|
3780
|
+
system: "yogini" | "vimshottari" | "ashtottari";
|
|
3781
|
+
moon_nakshatra: string;
|
|
3782
|
+
balance_years: number;
|
|
3783
|
+
active?: {
|
|
3784
|
+
target_utc: string;
|
|
3785
|
+
maha: string | null;
|
|
3786
|
+
antar: string | null;
|
|
3787
|
+
pratyantar?: string | null | undefined;
|
|
3788
|
+
} | undefined;
|
|
3789
|
+
start_lord?: string | undefined;
|
|
3790
|
+
start_yogini?: string | undefined;
|
|
3791
|
+
}, {
|
|
3792
|
+
natal_utc: string;
|
|
3793
|
+
periods: {
|
|
3794
|
+
start: string;
|
|
3795
|
+
end: string;
|
|
3796
|
+
lord?: string | undefined;
|
|
3797
|
+
sub?: {
|
|
3798
|
+
start: string;
|
|
3799
|
+
end: string;
|
|
3800
|
+
lord?: string | undefined;
|
|
3801
|
+
yogini?: string | undefined;
|
|
3802
|
+
}[] | undefined;
|
|
3803
|
+
yogini?: string | undefined;
|
|
3804
|
+
}[];
|
|
3805
|
+
system: "yogini" | "vimshottari" | "ashtottari";
|
|
3806
|
+
moon_nakshatra: string;
|
|
3807
|
+
balance_years: number;
|
|
3808
|
+
active?: {
|
|
3809
|
+
target_utc: string;
|
|
3810
|
+
maha: string | null;
|
|
3811
|
+
antar: string | null;
|
|
3812
|
+
pratyantar?: string | null | undefined;
|
|
3813
|
+
} | undefined;
|
|
3814
|
+
start_lord?: string | undefined;
|
|
3815
|
+
start_yogini?: string | undefined;
|
|
3816
|
+
}>;
|
|
3817
|
+
readonly vargas: z.ZodObject<{
|
|
3818
|
+
natal_utc: z.ZodString;
|
|
3819
|
+
zodiac: z.ZodEnum<["tropical", "sidereal:lahiri", "sidereal:fagan_bradley", "sidereal:krishnamurti", "sidereal:raman", "sidereal:yukteshwar", "sidereal:galcent_0sag", "sidereal:true_citra"]>;
|
|
3820
|
+
charts: z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
3821
|
+
sign: z.ZodString;
|
|
3822
|
+
sign_index: z.ZodNumber;
|
|
3823
|
+
division: z.ZodNumber;
|
|
3824
|
+
}, "strip", z.ZodTypeAny, {
|
|
3825
|
+
sign: string;
|
|
3826
|
+
sign_index: number;
|
|
3827
|
+
division: number;
|
|
3828
|
+
}, {
|
|
3829
|
+
sign: string;
|
|
3830
|
+
sign_index: number;
|
|
3831
|
+
division: number;
|
|
3832
|
+
}>>>;
|
|
3833
|
+
}, "strip", z.ZodTypeAny, {
|
|
3834
|
+
zodiac: "tropical" | "sidereal:lahiri" | "sidereal:fagan_bradley" | "sidereal:krishnamurti" | "sidereal:raman" | "sidereal:yukteshwar" | "sidereal:galcent_0sag" | "sidereal:true_citra";
|
|
3835
|
+
natal_utc: string;
|
|
3836
|
+
charts: Record<string, Record<string, {
|
|
3837
|
+
sign: string;
|
|
3838
|
+
sign_index: number;
|
|
3839
|
+
division: number;
|
|
3840
|
+
}>>;
|
|
3841
|
+
}, {
|
|
3842
|
+
zodiac: "tropical" | "sidereal:lahiri" | "sidereal:fagan_bradley" | "sidereal:krishnamurti" | "sidereal:raman" | "sidereal:yukteshwar" | "sidereal:galcent_0sag" | "sidereal:true_citra";
|
|
3843
|
+
natal_utc: string;
|
|
3844
|
+
charts: Record<string, Record<string, {
|
|
3845
|
+
sign: string;
|
|
3846
|
+
sign_index: number;
|
|
3847
|
+
division: number;
|
|
3848
|
+
}>>;
|
|
3849
|
+
}>;
|
|
3850
|
+
readonly yogas: z.ZodObject<{
|
|
3851
|
+
natal_utc: z.ZodString;
|
|
3852
|
+
zodiac: z.ZodEnum<["tropical", "sidereal:lahiri", "sidereal:fagan_bradley", "sidereal:krishnamurti", "sidereal:raman", "sidereal:yukteshwar", "sidereal:galcent_0sag", "sidereal:true_citra"]>;
|
|
3853
|
+
yogas: z.ZodArray<z.ZodObject<{
|
|
3854
|
+
yoga: z.ZodString;
|
|
3855
|
+
planets: z.ZodArray<z.ZodString, "many">;
|
|
3856
|
+
}, "strip", z.ZodTypeAny, {
|
|
3857
|
+
yoga: string;
|
|
3858
|
+
planets: string[];
|
|
3859
|
+
}, {
|
|
3860
|
+
yoga: string;
|
|
3861
|
+
planets: string[];
|
|
3862
|
+
}>, "many">;
|
|
3863
|
+
kemadruma: z.ZodBoolean;
|
|
3864
|
+
raja_yogas: z.ZodArray<z.ZodObject<{
|
|
3865
|
+
lords: z.ZodArray<z.ZodString, "many">;
|
|
3866
|
+
via: z.ZodString;
|
|
3867
|
+
}, "strip", z.ZodTypeAny, {
|
|
3868
|
+
lords: string[];
|
|
3869
|
+
via: string;
|
|
3870
|
+
}, {
|
|
3871
|
+
lords: string[];
|
|
3872
|
+
via: string;
|
|
3873
|
+
}>, "many">;
|
|
3874
|
+
dhana_yogas: z.ZodArray<z.ZodObject<{
|
|
3875
|
+
lords: z.ZodArray<z.ZodString, "many">;
|
|
3876
|
+
via: z.ZodString;
|
|
3877
|
+
}, "strip", z.ZodTypeAny, {
|
|
3878
|
+
lords: string[];
|
|
3879
|
+
via: string;
|
|
3880
|
+
}, {
|
|
3881
|
+
lords: string[];
|
|
3882
|
+
via: string;
|
|
3883
|
+
}>, "many">;
|
|
3884
|
+
yogakarakas: z.ZodArray<z.ZodString, "many">;
|
|
3885
|
+
}, "strip", z.ZodTypeAny, {
|
|
3886
|
+
zodiac: "tropical" | "sidereal:lahiri" | "sidereal:fagan_bradley" | "sidereal:krishnamurti" | "sidereal:raman" | "sidereal:yukteshwar" | "sidereal:galcent_0sag" | "sidereal:true_citra";
|
|
3887
|
+
natal_utc: string;
|
|
3888
|
+
yogas: {
|
|
3889
|
+
yoga: string;
|
|
3890
|
+
planets: string[];
|
|
3891
|
+
}[];
|
|
3892
|
+
kemadruma: boolean;
|
|
3893
|
+
raja_yogas: {
|
|
3894
|
+
lords: string[];
|
|
3895
|
+
via: string;
|
|
3896
|
+
}[];
|
|
3897
|
+
dhana_yogas: {
|
|
3898
|
+
lords: string[];
|
|
3899
|
+
via: string;
|
|
3900
|
+
}[];
|
|
3901
|
+
yogakarakas: string[];
|
|
3902
|
+
}, {
|
|
3903
|
+
zodiac: "tropical" | "sidereal:lahiri" | "sidereal:fagan_bradley" | "sidereal:krishnamurti" | "sidereal:raman" | "sidereal:yukteshwar" | "sidereal:galcent_0sag" | "sidereal:true_citra";
|
|
3904
|
+
natal_utc: string;
|
|
3905
|
+
yogas: {
|
|
3906
|
+
yoga: string;
|
|
3907
|
+
planets: string[];
|
|
3908
|
+
}[];
|
|
3909
|
+
kemadruma: boolean;
|
|
3910
|
+
raja_yogas: {
|
|
3911
|
+
lords: string[];
|
|
3912
|
+
via: string;
|
|
3913
|
+
}[];
|
|
3914
|
+
dhana_yogas: {
|
|
3915
|
+
lords: string[];
|
|
3916
|
+
via: string;
|
|
3917
|
+
}[];
|
|
3918
|
+
yogakarakas: string[];
|
|
3335
3919
|
}>;
|
|
3336
3920
|
};
|
|
3337
3921
|
export interface BuildServerOptions {
|
package/dist/src/server.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* caelus-mcp -- MCP server for the caelus ephemeris engine.
|
|
4
4
|
*
|
|
5
5
|
* Design (per 2026 MCP practice): one bounded context (chart computation),
|
|
6
|
-
* a small curated tool surface (
|
|
6
|
+
* a small curated tool surface (twenty-two outcome-level tools, not API wrappers),
|
|
7
7
|
* and token-frugal outputs (positions to 0.01 deg, terse keys, no prose --
|
|
8
8
|
* the model does the interpreting, the server does the math).
|
|
9
9
|
*
|
|
@@ -17,7 +17,7 @@ import { dirname, join } from "node:path";
|
|
|
17
17
|
import { fileURLToPath } from "node:url";
|
|
18
18
|
import { createRequire } from "node:module";
|
|
19
19
|
import { realpathSync } from "node:fs";
|
|
20
|
-
import { Engine, BODIES, julianDay, mod, riseSet, crossings, lunarPhases, stations, lunarEclipses, solarEclipses, ASPECTS, DEFAULT_ORBS, SIGNS as SIGN_NAMES, dignities, solarPhase, aspectPhase, planetaryHour, voidOfCourse, CAZIMI_DEG, COMBUST_DEG, UNDER_BEAMS_DEG, solarReturn, lunarReturn, progressedLongitude, directedLongitude, solarArc, progressedJd, compositeLongitudes, davisonParams, midpointLon, dignityOf, isDayChart, planetarySect, inSect, lots, HERMETIC_LOTS, profectionAt, firdaria, firdariaActive, zrRelease, zrActive, lotSpirit, lotFortune, primaryDirections, } from "caelus";
|
|
20
|
+
import { Engine, BODIES, julianDay, mod, riseSet, crossings, lunarPhases, stations, lunarEclipses, solarEclipses, ASPECTS, DEFAULT_ORBS, SIGNS as SIGN_NAMES, dignities, solarPhase, aspectPhase, planetaryHour, voidOfCourse, CAZIMI_DEG, COMBUST_DEG, UNDER_BEAMS_DEG, solarReturn, lunarReturn, progressedLongitude, directedLongitude, solarArc, progressedJd, compositeLongitudes, davisonParams, midpointLon, dignityOf, isDayChart, planetarySect, inSect, lots, HERMETIC_LOTS, profectionAt, firdaria, firdariaActive, zrRelease, zrActive, lotSpirit, lotFortune, primaryDirections, mundaneDirections, nakshatra, vimshottariDashas, vimshottariAt, yoginiDashas, yoginiAt, ashtottariDashas, ashtottariAt, varga, VARGA_DIVISIONS, yogasAt, kemadrumaAt, rajaYogasAt, dhanaYogasAt, } from "caelus";
|
|
21
21
|
import { loadNodeData } from "caelus/node";
|
|
22
22
|
const require = createRequire(import.meta.url);
|
|
23
23
|
// Read our own version relative to this file (dist/src/server.js -> the package
|
|
@@ -80,6 +80,10 @@ const ZODIACS = [
|
|
|
80
80
|
];
|
|
81
81
|
const zodiacSchema = z.enum(ZODIACS).default("tropical")
|
|
82
82
|
.describe("tropical (default) or sidereal:<ayanamsa>");
|
|
83
|
+
// Jyotish techniques (nakshatras, vargas, dashas, yogas) are sidereal by
|
|
84
|
+
// definition; default these tools to Lahiri rather than tropical.
|
|
85
|
+
const siderealZodiac = z.enum(ZODIACS).default("sidereal:lahiri")
|
|
86
|
+
.describe("sidereal ayanamsa (default sidereal:lahiri); these are sidereal techniques");
|
|
83
87
|
// ----------------------------------------------------- resource payloads
|
|
84
88
|
// Loaded lazily on first read of the accuracy resource and memoized. Kept off
|
|
85
89
|
// the module top level so importing this file into the bundled Streamable HTTP
|
|
@@ -177,6 +181,40 @@ function chartPayload(engine, iso, lat, lon, hs, zodiac = "tropical") {
|
|
|
177
181
|
};
|
|
178
182
|
}
|
|
179
183
|
const text = (obj) => ({ content: [{ type: "text", text: JSON.stringify(obj) }] });
|
|
184
|
+
// ---------------------------------------------------------------- chart widget (MCP Apps / Apps SDK)
|
|
185
|
+
// natal_chart and current_sky can render the chart wheel in-host (ChatGPT and
|
|
186
|
+
// other MCP-UI / Apps-SDK hosts). The widget loads a self-contained bundle
|
|
187
|
+
// (apps/web/widget -> /embed/chart-widget.js) directly in the host's own
|
|
188
|
+
// sandbox — no nested iframe — and mounts caelus-wheel from the tool's
|
|
189
|
+
// structuredContent. Server-side half only; see docs/mcp-app-wiring.md.
|
|
190
|
+
const EMBED_ORIGIN = process.env.CAELUS_EMBED_ORIGIN ?? "https://www.ephemengine.com";
|
|
191
|
+
const CHART_WIDGET_URI = "ui://widget/chart.html";
|
|
192
|
+
// The MCP Apps UI MIME type (current). Hosts only enable the UI bridge for it;
|
|
193
|
+
// ChatGPT additionally honours the legacy openai/* _meta aliases set below.
|
|
194
|
+
const CHART_WIDGET_MIME = "text/html;profile=mcp-app";
|
|
195
|
+
// Bind the two chart tools to the widget. Both the standard (_meta.ui.resourceUri)
|
|
196
|
+
// and the ChatGPT compatibility alias (openai/outputTemplate) point at the same
|
|
197
|
+
// resource, so the binding survives across hosts.
|
|
198
|
+
const CHART_TOOL_META = {
|
|
199
|
+
ui: { resourceUri: CHART_WIDGET_URI },
|
|
200
|
+
"openai/outputTemplate": CHART_WIDGET_URI,
|
|
201
|
+
};
|
|
202
|
+
// The widget shell: a root element plus the bundle loaded directly from the
|
|
203
|
+
// embed origin (a script, not an iframe — so the CSP needs only resourceDomains,
|
|
204
|
+
// never the heavily-scrutinised frameDomains). The bundle reads the chart from
|
|
205
|
+
// the MCP Apps tool-result message / window.openai.toolOutput. `version` is a
|
|
206
|
+
// cache-buster so a release always loads fresh JS.
|
|
207
|
+
const chartWidgetHtml = (version) => `<!doctype html><meta charset="utf-8">
|
|
208
|
+
<style>html,body{margin:0;height:100%;background:#0e0e14}#caelus-chart-root{position:fixed;inset:0;display:grid;place-items:center;overflow:hidden}</style>
|
|
209
|
+
<div id="caelus-chart-root"></div>
|
|
210
|
+
<script src="${EMBED_ORIGIN}/embed/chart-widget.js?v=${encodeURIComponent(version)}"></script>`;
|
|
211
|
+
// Tool result for the two chart tools: the existing text payload (unchanged for
|
|
212
|
+
// non-UI clients) plus structuredContent, which UI hosts hand to the widget as
|
|
213
|
+
// its tool output. The two carry the same object.
|
|
214
|
+
const chartResult = (payload) => ({
|
|
215
|
+
content: [{ type: "text", text: JSON.stringify(payload) }],
|
|
216
|
+
structuredContent: payload,
|
|
217
|
+
});
|
|
180
218
|
// ---------------------------------------------------------------- output schemas
|
|
181
219
|
// Exported so the integration test validates responses against the same shape
|
|
182
220
|
// the server promises. Kept permissive on optional keys (rx, fallback fields).
|
|
@@ -360,10 +398,74 @@ const directionOut = z.object({
|
|
|
360
398
|
years: z.number(),
|
|
361
399
|
date: z.string(),
|
|
362
400
|
});
|
|
401
|
+
const mundaneDirectionOut = z.object({
|
|
402
|
+
promissor: z.string(),
|
|
403
|
+
significator: z.string(),
|
|
404
|
+
arc: z.number(),
|
|
405
|
+
years: z.number(),
|
|
406
|
+
date: z.string(),
|
|
407
|
+
});
|
|
363
408
|
export const directionsOut = z.object({
|
|
364
409
|
natal_utc: z.string(),
|
|
365
410
|
key: z.enum(["ptolemy", "naibod"]),
|
|
366
411
|
directions: z.array(directionOut),
|
|
412
|
+
mundane: z.array(mundaneDirectionOut).optional(),
|
|
413
|
+
});
|
|
414
|
+
export const nakshatrasOut = z.object({
|
|
415
|
+
natal_utc: z.string(),
|
|
416
|
+
zodiac: z.enum(ZODIACS),
|
|
417
|
+
points: z.record(z.string(), z.object({
|
|
418
|
+
nakshatra: z.string(),
|
|
419
|
+
pada: z.number().int().min(1).max(4),
|
|
420
|
+
lord: z.string(),
|
|
421
|
+
deg: z.number(),
|
|
422
|
+
})),
|
|
423
|
+
});
|
|
424
|
+
const dashaSubOut = z.object({
|
|
425
|
+
lord: z.string().optional(),
|
|
426
|
+
yogini: z.string().optional(),
|
|
427
|
+
start: z.string(),
|
|
428
|
+
end: z.string(),
|
|
429
|
+
});
|
|
430
|
+
export const dashaOut = z.object({
|
|
431
|
+
natal_utc: z.string(),
|
|
432
|
+
system: z.enum(["vimshottari", "yogini", "ashtottari"]),
|
|
433
|
+
moon_nakshatra: z.string(),
|
|
434
|
+
start_lord: z.string().optional(),
|
|
435
|
+
start_yogini: z.string().optional(),
|
|
436
|
+
balance_years: z.number(),
|
|
437
|
+
periods: z.array(z.object({
|
|
438
|
+
lord: z.string().optional(),
|
|
439
|
+
yogini: z.string().optional(),
|
|
440
|
+
start: z.string(),
|
|
441
|
+
end: z.string(),
|
|
442
|
+
sub: z.array(dashaSubOut).optional(),
|
|
443
|
+
})),
|
|
444
|
+
active: z.object({
|
|
445
|
+
target_utc: z.string(),
|
|
446
|
+
maha: z.string().nullable(),
|
|
447
|
+
antar: z.string().nullable(),
|
|
448
|
+
pratyantar: z.string().nullable().optional(),
|
|
449
|
+
}).optional(),
|
|
450
|
+
});
|
|
451
|
+
export const vargasOut = z.object({
|
|
452
|
+
natal_utc: z.string(),
|
|
453
|
+
zodiac: z.enum(ZODIACS),
|
|
454
|
+
charts: z.record(z.string(), z.record(z.string(), z.object({
|
|
455
|
+
sign: z.string(),
|
|
456
|
+
sign_index: z.number().int().min(0).max(11),
|
|
457
|
+
division: z.number().int(),
|
|
458
|
+
}))),
|
|
459
|
+
});
|
|
460
|
+
const lordPairOut = z.object({ lords: z.array(z.string()), via: z.string() });
|
|
461
|
+
export const yogasOut = z.object({
|
|
462
|
+
natal_utc: z.string(),
|
|
463
|
+
zodiac: z.enum(ZODIACS),
|
|
464
|
+
yogas: z.array(z.object({ yoga: z.string(), planets: z.array(z.string()) })),
|
|
465
|
+
kemadruma: z.boolean(),
|
|
466
|
+
raja_yogas: z.array(lordPairOut),
|
|
467
|
+
dhana_yogas: z.array(lordPairOut),
|
|
468
|
+
yogakarakas: z.array(z.string()),
|
|
367
469
|
});
|
|
368
470
|
export const OUTPUT_SCHEMAS = {
|
|
369
471
|
natal_chart: chartOut,
|
|
@@ -384,13 +486,19 @@ export const OUTPUT_SCHEMAS = {
|
|
|
384
486
|
firdaria: firdariaOut,
|
|
385
487
|
releasing: releasingOut,
|
|
386
488
|
directions: directionsOut,
|
|
489
|
+
nakshatras: nakshatrasOut,
|
|
490
|
+
dasha: dashaOut,
|
|
491
|
+
vargas: vargasOut,
|
|
492
|
+
yogas: yogasOut,
|
|
387
493
|
};
|
|
388
494
|
export function buildServer(engine = defaultEngine(), opts = {}) {
|
|
389
|
-
const
|
|
495
|
+
const version = opts.version ?? VERSION;
|
|
496
|
+
const server = new McpServer({ name: "caelus", version });
|
|
390
497
|
server.registerTool("natal_chart", {
|
|
391
498
|
description: "A person's birth chart. Requires their exact birth date+time and birthplace (all three: date, lat, lon). Use this — not current_sky — whenever the question is about someone's natal/birth chart. Returns 13 bodies (sun–pluto, chiron, nodes) with sign, house, retrograde, speed; ASC/MC; cusps; major aspects with orbs. Vs Swiss Ephemeris (1900–2099): Sun–Saturn ≤1″, Uranus ≤1.9″, Neptune ≤4.6″, Moon ≤2.5″, Pluto ≤2.5″ (series valid 1885–2099), Chiron ≤1″, mean node ≤1″, true node ≤ 1′ vs SE's built-in ephemeris.",
|
|
392
499
|
inputSchema: { ...birth, house_system: houseSys, zodiac: zodiacSchema },
|
|
393
|
-
|
|
500
|
+
_meta: CHART_TOOL_META,
|
|
501
|
+
}, async ({ date, lat, lon, house_system, zodiac }) => chartResult(chartPayload(engine, date, lat, lon, house_system, zodiac)));
|
|
394
502
|
server.registerTool("current_sky", {
|
|
395
503
|
description: "The sky at a moment and place — not tied to any person. Use for \"what's the sky/transits right now\" or the chart of a non-birth event. Date defaults to now; lat/lon default to 0,0 (geocentric on the equator at the prime meridian), where houses and ASC/MC are nominal — pass a real location if houses matter. For a specific person's birth chart use natal_chart instead. Returns positions, houses, retrogrades, aspects.",
|
|
396
504
|
inputSchema: {
|
|
@@ -400,7 +508,8 @@ export function buildServer(engine = defaultEngine(), opts = {}) {
|
|
|
400
508
|
house_system: houseSys,
|
|
401
509
|
zodiac: zodiacSchema,
|
|
402
510
|
},
|
|
403
|
-
|
|
511
|
+
_meta: CHART_TOOL_META,
|
|
512
|
+
}, async ({ date, lat, lon, house_system, zodiac }) => chartResult(chartPayload(engine, date ?? new Date().toISOString(), lat, lon, house_system, zodiac)));
|
|
404
513
|
server.registerTool("transits", {
|
|
405
514
|
description: "Transiting planets vs natal chart: aspects within orb (applying/separating), natal house per transiting body.",
|
|
406
515
|
inputSchema: {
|
|
@@ -891,16 +1000,17 @@ export function buildServer(engine = defaultEngine(), opts = {}) {
|
|
|
891
1000
|
return text(payload);
|
|
892
1001
|
});
|
|
893
1002
|
server.registerTool("directions", {
|
|
894
|
-
description: "Primary (mundane) directions of the seven traditional planets to the four angles (MC, IC, Ascendant, Descendant). The diurnal rotation carries
|
|
1003
|
+
description: "Primary (mundane) directions of the seven traditional planets to the four angles (MC, IC, Ascendant, Descendant), and optionally between the planets themselves. The diurnal rotation carries a body to the angle (or a promissor to a significator); the arc of rotation, converted by a time key (Naibod 0.9856473°/yr by default, or Ptolemy 1°/yr), gives the age of the direction. Returns the directions within max_years, sorted by age, each with its arc, age in years, and UTC date. With include_mundane, also returns the planet-to-planet (promissor → significator) directions. Circumpolar bodies have no Ascendant/Descendant directions. Needs the birth time and place; equatorial, so zodiac is irrelevant.",
|
|
895
1004
|
inputSchema: {
|
|
896
1005
|
...birth,
|
|
897
1006
|
key: z.enum(["naibod", "ptolemy"]).optional().describe("time key: naibod (0.9856473°/yr, default) or ptolemy (1°/yr)"),
|
|
898
1007
|
max_years: z.number().positive().optional().describe("only directions reached within this many years of life (default 90)"),
|
|
1008
|
+
include_mundane: z.boolean().optional().describe("also return inter-planetary (promissor → significator) directions (default false)"),
|
|
899
1009
|
},
|
|
900
|
-
}, async ({ date, lat, lon, key = "naibod", max_years = 90 }) => {
|
|
1010
|
+
}, async ({ date, lat, lon, key = "naibod", max_years = 90, include_mundane = false }) => {
|
|
901
1011
|
const natalJd = jdFromIso(date);
|
|
902
1012
|
const dirs = primaryDirections(engine, natalJd, lat, lon, undefined, key, max_years);
|
|
903
|
-
|
|
1013
|
+
const payload = {
|
|
904
1014
|
natal_utc: date,
|
|
905
1015
|
key,
|
|
906
1016
|
directions: dirs.map((d) => ({
|
|
@@ -910,9 +1020,167 @@ export function buildServer(engine = defaultEngine(), opts = {}) {
|
|
|
910
1020
|
years: r2(d.years),
|
|
911
1021
|
date: isoFromJd(d.jd),
|
|
912
1022
|
})),
|
|
1023
|
+
};
|
|
1024
|
+
if (include_mundane) {
|
|
1025
|
+
const mundane = mundaneDirections(engine, natalJd, lat, lon, undefined, key, max_years);
|
|
1026
|
+
payload.mundane = mundane.map((d) => ({
|
|
1027
|
+
promissor: d.promissor,
|
|
1028
|
+
significator: d.significator,
|
|
1029
|
+
arc: r2(d.arc),
|
|
1030
|
+
years: r2(d.years),
|
|
1031
|
+
date: isoFromJd(d.jd),
|
|
1032
|
+
}));
|
|
1033
|
+
}
|
|
1034
|
+
return text(payload);
|
|
1035
|
+
});
|
|
1036
|
+
server.registerTool("nakshatras", {
|
|
1037
|
+
description: "The nakshatra (one of the 27 lunar mansions of 13°20′) of each classical point on the sidereal zodiac: the seven traditional planets and the Ascendant (lagna). Per point: the nakshatra name, its pada (quarter, 1–4), the ruling planet (the Vimshottari lord), and degrees into the nakshatra. The Moon's nakshatra (janma nakshatra) anchors the Vimshottari dasha. Sidereal by definition; Lahiri ayanamsa by default. Needs the birth time and place for the Ascendant.",
|
|
1038
|
+
inputSchema: { ...birth, zodiac: siderealZodiac },
|
|
1039
|
+
}, async ({ date, lat, lon, zodiac }) => {
|
|
1040
|
+
const natalJd = jdFromIso(date);
|
|
1041
|
+
const chart = engine.chartAt(natalJd, lat, lon, { zodiac });
|
|
1042
|
+
const desc = (lonDeg) => {
|
|
1043
|
+
const n = nakshatra(lonDeg);
|
|
1044
|
+
return { nakshatra: n.name, pada: n.pada, lord: n.lord, deg: r2(n.pos) };
|
|
1045
|
+
};
|
|
1046
|
+
const points = {};
|
|
1047
|
+
for (const b of TRADITIONAL)
|
|
1048
|
+
points[b] = desc(chart.bodies[b].lon);
|
|
1049
|
+
points.asc = desc(chart.angles.asc);
|
|
1050
|
+
return text({ natal_utc: date, zodiac, points });
|
|
1051
|
+
});
|
|
1052
|
+
server.registerTool("dasha", {
|
|
1053
|
+
description: "Vedic dasha periods — planetary time-lord cycles started from the Moon's birth nakshatra. system selects Vimshottari (120-year, the standard), Yogini (36-year, eight yoginis), or Ashtottari (108-year). Returns the period timeline (mahadasha → antardasha) with UTC start/end, the balance of the first period at birth, and — when target_date is given — the lords active then (Vimshottari also gives the pratyantardasha). Sidereal; Lahiri by default. Needs the birth time and place.",
|
|
1054
|
+
inputSchema: {
|
|
1055
|
+
...birth,
|
|
1056
|
+
system: z.enum(["vimshottari", "yogini", "ashtottari"]).default("vimshottari")
|
|
1057
|
+
.describe("dasha system: vimshottari (120y), yogini (36y), or ashtottari (108y)"),
|
|
1058
|
+
target_date: z.string().optional().describe("UTC ISO date to read the active lords for; omit for the timeline only"),
|
|
1059
|
+
levels: z.number().int().min(1).max(2).optional().describe("deepest timeline level: 1 (maha) or 2 (maha+antar, default)"),
|
|
1060
|
+
zodiac: siderealZodiac,
|
|
1061
|
+
},
|
|
1062
|
+
}, async ({ date, lat, lon, system, target_date, levels = 2, zodiac }) => {
|
|
1063
|
+
const natalJd = jdFromIso(date);
|
|
1064
|
+
const moonLon = engine.longitude("moon", natalJd, { zodiac });
|
|
1065
|
+
const moonNak = nakshatra(moonLon).name;
|
|
1066
|
+
const targetJd = target_date !== undefined ? jdFromIso(target_date) : undefined;
|
|
1067
|
+
const isoSub = (s) => ({ lord: s.lord, start: isoFromJd(s.start), end: isoFromJd(s.end) });
|
|
1068
|
+
switch (system) {
|
|
1069
|
+
case "vimshottari": {
|
|
1070
|
+
const tl = vimshottariDashas(moonLon, natalJd, levels);
|
|
1071
|
+
const periods = tl.dashas.map((d) => ({
|
|
1072
|
+
lord: d.lord, start: isoFromJd(d.start), end: isoFromJd(d.end),
|
|
1073
|
+
...(levels >= 2 ? { sub: d.sub.map(isoSub) } : {}),
|
|
1074
|
+
}));
|
|
1075
|
+
const payload = {
|
|
1076
|
+
natal_utc: date, system, moon_nakshatra: moonNak,
|
|
1077
|
+
start_lord: tl.start_lord, balance_years: r2(tl.balance_years), periods,
|
|
1078
|
+
};
|
|
1079
|
+
if (targetJd !== undefined) {
|
|
1080
|
+
const a = vimshottariAt(engine, natalJd, targetJd, zodiac);
|
|
1081
|
+
payload.active = { target_utc: target_date, maha: a.maha ?? null, antar: a.antar ?? null, pratyantar: a.pratyantar ?? null };
|
|
1082
|
+
}
|
|
1083
|
+
return text(payload);
|
|
1084
|
+
}
|
|
1085
|
+
case "yogini": {
|
|
1086
|
+
const tl = yoginiDashas(moonLon, natalJd, levels);
|
|
1087
|
+
const periods = tl.dashas.map((d) => ({
|
|
1088
|
+
yogini: d.yogini, lord: d.lord, start: isoFromJd(d.start), end: isoFromJd(d.end),
|
|
1089
|
+
...(levels >= 2 ? { sub: d.sub.map((s) => ({ yogini: s.yogini, lord: s.lord, start: isoFromJd(s.start), end: isoFromJd(s.end) })) } : {}),
|
|
1090
|
+
}));
|
|
1091
|
+
const payload = {
|
|
1092
|
+
natal_utc: date, system, moon_nakshatra: moonNak,
|
|
1093
|
+
start_yogini: tl.start_yogini, balance_years: r2(tl.balance_years), periods,
|
|
1094
|
+
};
|
|
1095
|
+
if (targetJd !== undefined) {
|
|
1096
|
+
const a = yoginiAt(engine, natalJd, targetJd, zodiac);
|
|
1097
|
+
payload.active = { target_utc: target_date, maha: a.maha ?? null, antar: a.antar ?? null };
|
|
1098
|
+
}
|
|
1099
|
+
return text(payload);
|
|
1100
|
+
}
|
|
1101
|
+
case "ashtottari": {
|
|
1102
|
+
const tl = ashtottariDashas(moonLon, natalJd, levels);
|
|
1103
|
+
const periods = tl.dashas.map((d) => ({
|
|
1104
|
+
lord: d.lord, start: isoFromJd(d.start), end: isoFromJd(d.end),
|
|
1105
|
+
...(levels >= 2 ? { sub: d.sub.map(isoSub) } : {}),
|
|
1106
|
+
}));
|
|
1107
|
+
const payload = {
|
|
1108
|
+
natal_utc: date, system, moon_nakshatra: moonNak,
|
|
1109
|
+
start_lord: tl.start_lord, balance_years: r2(tl.balance_years), periods,
|
|
1110
|
+
};
|
|
1111
|
+
if (targetJd !== undefined) {
|
|
1112
|
+
const a = ashtottariAt(engine, natalJd, targetJd, zodiac);
|
|
1113
|
+
payload.active = { target_utc: target_date, maha: a.maha ?? null, antar: a.antar ?? null };
|
|
1114
|
+
}
|
|
1115
|
+
return text(payload);
|
|
1116
|
+
}
|
|
1117
|
+
default: {
|
|
1118
|
+
const _exhaustive = system;
|
|
1119
|
+
throw new Error(`unknown dasha system: ${String(_exhaustive)}`);
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
});
|
|
1123
|
+
server.registerTool("vargas", {
|
|
1124
|
+
description: "Parashari divisional charts (vargas): the sign of each of the seven planets and the Ascendant in the requested D-charts — D1 rasi, D2 hora, D3 drekkana, D9 navamsa, D10 dasamsa, D12 dwadasamsa, D30 trimsamsa. Per point in each chart: the divisional sign and the division number within the rasi. The navamsa (D9) is the most consulted after the rasi. Sidereal; Lahiri by default. Needs the birth time and place for the Ascendant.",
|
|
1125
|
+
inputSchema: {
|
|
1126
|
+
...birth,
|
|
1127
|
+
divisions: z.array(z.number().int().refine((n) => VARGA_DIVISIONS.includes(n), "unsupported division"))
|
|
1128
|
+
.optional().describe(`subset of ${VARGA_DIVISIONS.join("/")} (default all)`),
|
|
1129
|
+
zodiac: siderealZodiac,
|
|
1130
|
+
},
|
|
1131
|
+
}, async ({ date, lat, lon, divisions, zodiac }) => {
|
|
1132
|
+
const natalJd = jdFromIso(date);
|
|
1133
|
+
const chart = engine.chartAt(natalJd, lat, lon, { zodiac });
|
|
1134
|
+
const ns = divisions && divisions.length ? divisions : VARGA_DIVISIONS;
|
|
1135
|
+
const lons = { asc: chart.angles.asc };
|
|
1136
|
+
for (const b of TRADITIONAL)
|
|
1137
|
+
lons[b] = chart.bodies[b].lon;
|
|
1138
|
+
const charts = {};
|
|
1139
|
+
for (const n of ns) {
|
|
1140
|
+
const c = {};
|
|
1141
|
+
for (const [name, lonDeg] of Object.entries(lons)) {
|
|
1142
|
+
const v = varga(lonDeg, n);
|
|
1143
|
+
c[name] = { sign: v.sign, sign_index: v.sign_index, division: v.division };
|
|
1144
|
+
}
|
|
1145
|
+
charts[`D${n}`] = c;
|
|
1146
|
+
}
|
|
1147
|
+
return text({ natal_utc: date, zodiac, charts });
|
|
1148
|
+
});
|
|
1149
|
+
server.registerTool("yogas", {
|
|
1150
|
+
description: "Vedic yogas (planetary combinations) on the sidereal rasi chart: the five Pancha Mahapurusha yogas (Ruchaka, Bhadra, Hamsa, Malavya, Shasha), Gajakesari, Budha-Aditya, and Chandra-Mangala; whether Kemadruma (the isolated-Moon yoga) is present; the raja yogas (a kendra lord associating with a trikona lord) and dhana (wealth) yogas, each as the lord pair and how they associate (conjunction, aspect, or exchange); and the chart's yogakarakas (a planet ruling both a kendra and a trikona). Sidereal; Lahiri by default. Needs the birth time and place.",
|
|
1151
|
+
inputSchema: { ...birth, zodiac: siderealZodiac },
|
|
1152
|
+
}, async ({ date, lat, lon, zodiac }) => {
|
|
1153
|
+
const natalJd = jdFromIso(date);
|
|
1154
|
+
const placement = yogasAt(engine, natalJd, lat, lon, zodiac);
|
|
1155
|
+
const kema = kemadrumaAt(engine, natalJd, lat, lon, false, false, zodiac);
|
|
1156
|
+
const { raja, yogakarakas } = rajaYogasAt(engine, natalJd, lat, lon, zodiac);
|
|
1157
|
+
const dhana = dhanaYogasAt(engine, natalJd, lat, lon, zodiac);
|
|
1158
|
+
return text({
|
|
1159
|
+
natal_utc: date, zodiac,
|
|
1160
|
+
yogas: placement,
|
|
1161
|
+
kemadruma: kema.present,
|
|
1162
|
+
raja_yogas: raja,
|
|
1163
|
+
dhana_yogas: dhana,
|
|
1164
|
+
yogakarakas,
|
|
913
1165
|
});
|
|
914
1166
|
});
|
|
915
1167
|
// --------------------------------------------------------- resources
|
|
1168
|
+
// Chart wheel widget (MCP Apps / Apps SDK). The CSP allowlists the embed
|
|
1169
|
+
// origin only for loading the widget script (resourceDomains) — no
|
|
1170
|
+
// frameDomains, since the bundle renders directly in the host sandbox rather
|
|
1171
|
+
// than nesting an iframe. The legacy openai/widgetCSP mirror keeps older
|
|
1172
|
+
// ChatGPT happy.
|
|
1173
|
+
server.registerResource("chart-widget", CHART_WIDGET_URI, {
|
|
1174
|
+
title: "Chart wheel",
|
|
1175
|
+
description: "Renders the natal_chart / current_sky payload as a caelus-wheel chart.",
|
|
1176
|
+
mimeType: CHART_WIDGET_MIME,
|
|
1177
|
+
_meta: {
|
|
1178
|
+
ui: { csp: { connectDomains: [], resourceDomains: [EMBED_ORIGIN] } },
|
|
1179
|
+
"openai/widgetCSP": { connect_domains: [], resource_domains: [EMBED_ORIGIN] },
|
|
1180
|
+
},
|
|
1181
|
+
}, async (uri) => ({
|
|
1182
|
+
contents: [{ uri: uri.href, mimeType: CHART_WIDGET_MIME, text: chartWidgetHtml(version) }],
|
|
1183
|
+
}));
|
|
916
1184
|
server.registerResource("accuracy", "caelus://accuracy", {
|
|
917
1185
|
title: "Validation table",
|
|
918
1186
|
description: "Per-body accuracy: vs Swiss Ephemeris (swiss) and JPL Horizons apparent positions (jpl).",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "caelus-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"mcpName": "io.github.heavyblotto/caelus-mcp",
|
|
5
5
|
"description": "MCP server for caelus chart computation.",
|
|
6
6
|
"type": "module",
|
|
@@ -15,12 +15,16 @@
|
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
17
17
|
"zod": "^3.24.0",
|
|
18
|
-
"caelus": "^0.
|
|
18
|
+
"caelus": "^0.14.0"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"ajv": "^8.17.1"
|
|
22
22
|
},
|
|
23
23
|
"license": "MIT",
|
|
24
|
+
"publishConfig": {
|
|
25
|
+
"access": "public",
|
|
26
|
+
"provenance": true
|
|
27
|
+
},
|
|
24
28
|
"files": [
|
|
25
29
|
"dist/src"
|
|
26
30
|
],
|