ether-to-astro 1.0.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/.env.example +13 -0
- package/.github/pull_request_template.md +16 -0
- package/.github/workflows/release.yml +35 -0
- package/.github/workflows/test.yml +32 -0
- package/AGENTS.md +99 -0
- package/LICENSE +18 -0
- package/NOTICE.md +45 -0
- package/README.md +301 -0
- package/SETUP.md +70 -0
- package/TESTING_SUMMARY.md +238 -0
- package/TEST_SUITE_STATUS.md +218 -0
- package/biome.json +48 -0
- package/dist/astro-service.d.ts +98 -0
- package/dist/astro-service.js +496 -0
- package/dist/chart-types.d.ts +52 -0
- package/dist/chart-types.js +51 -0
- package/dist/charts.d.ts +125 -0
- package/dist/charts.js +324 -0
- package/dist/cli.d.ts +7 -0
- package/dist/cli.js +472 -0
- package/dist/constants.d.ts +81 -0
- package/dist/constants.js +76 -0
- package/dist/eclipses.d.ts +85 -0
- package/dist/eclipses.js +184 -0
- package/dist/ephemeris.d.ts +120 -0
- package/dist/ephemeris.js +379 -0
- package/dist/formatter.d.ts +2 -0
- package/dist/formatter.js +22 -0
- package/dist/houses.d.ts +82 -0
- package/dist/houses.js +169 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +150 -0
- package/dist/loader.d.ts +2 -0
- package/dist/loader.js +31 -0
- package/dist/logger.d.ts +25 -0
- package/dist/logger.js +73 -0
- package/dist/profile-store.d.ts +48 -0
- package/dist/profile-store.js +156 -0
- package/dist/riseset.d.ts +82 -0
- package/dist/riseset.js +185 -0
- package/dist/storage.d.ts +10 -0
- package/dist/storage.js +40 -0
- package/dist/time-utils.d.ts +68 -0
- package/dist/time-utils.js +136 -0
- package/dist/tool-registry.d.ts +35 -0
- package/dist/tool-registry.js +307 -0
- package/dist/tool-result.d.ts +175 -0
- package/dist/tool-result.js +188 -0
- package/dist/transits.d.ts +108 -0
- package/dist/transits.js +263 -0
- package/dist/types.d.ts +450 -0
- package/dist/types.js +161 -0
- package/example-usage.md +131 -0
- package/natal-chart.json +187 -0
- package/package.json +61 -0
- package/scripts/download-ephemeris.js +115 -0
- package/setup.sh +21 -0
- package/src/astro-service.ts +710 -0
- package/src/chart-types.ts +125 -0
- package/src/charts.ts +399 -0
- package/src/cli.ts +694 -0
- package/src/constants.ts +89 -0
- package/src/eclipses.ts +226 -0
- package/src/ephemeris.ts +437 -0
- package/src/formatter.ts +25 -0
- package/src/houses.ts +202 -0
- package/src/index.ts +170 -0
- package/src/loader.ts +36 -0
- package/src/logger.ts +104 -0
- package/src/profile-store.ts +285 -0
- package/src/riseset.ts +229 -0
- package/src/time-utils.ts +167 -0
- package/src/tool-registry.ts +357 -0
- package/src/tool-result.ts +283 -0
- package/src/transits.ts +352 -0
- package/src/types.ts +547 -0
- package/tests/README.md +173 -0
- package/tests/TESTING_STRATEGY.md +178 -0
- package/tests/fixtures/bowen-yang-chart.ts +69 -0
- package/tests/fixtures/calculate-expected.ts +81 -0
- package/tests/fixtures/expected-results.ts +117 -0
- package/tests/fixtures/generate-expected-simple.ts +94 -0
- package/tests/helpers/date-fixtures.ts +15 -0
- package/tests/helpers/ephem.ts +11 -0
- package/tests/helpers/temp.ts +9 -0
- package/tests/setup.ts +11 -0
- package/tests/unit/astro-service.test.ts +323 -0
- package/tests/unit/chart-types.test.ts +18 -0
- package/tests/unit/charts-errors.test.ts +42 -0
- package/tests/unit/charts.test.ts +157 -0
- package/tests/unit/cli-commands.test.ts +82 -0
- package/tests/unit/cli-profiles.test.ts +128 -0
- package/tests/unit/cli.test.ts +191 -0
- package/tests/unit/constants.test.ts +26 -0
- package/tests/unit/correctness-critical.test.ts +408 -0
- package/tests/unit/eclipses.test.ts +108 -0
- package/tests/unit/ephemeris.test.ts +213 -0
- package/tests/unit/error-handling.test.ts +116 -0
- package/tests/unit/formatter.test.ts +29 -0
- package/tests/unit/houses-errors.test.ts +27 -0
- package/tests/unit/houses-validation.test.ts +164 -0
- package/tests/unit/houses.test.ts +205 -0
- package/tests/unit/profile-store.test.ts +163 -0
- package/tests/unit/real-user-charts.test.ts +148 -0
- package/tests/unit/riseset.test.ts +106 -0
- package/tests/unit/solver-edges.test.ts +197 -0
- package/tests/unit/time-utils-temporal.test.ts +303 -0
- package/tests/unit/time-utils.test.ts +173 -0
- package/tests/unit/tool-registry.test.ts +222 -0
- package/tests/unit/tool-result.test.ts +45 -0
- package/tests/unit/transit-correctness.test.ts +78 -0
- package/tests/unit/transits.test.ts +238 -0
- package/tests/validation/README.md +32 -0
- package/tests/validation/adapters/astrolog.ts +306 -0
- package/tests/validation/adapters/internal.ts +184 -0
- package/tests/validation/compare/eclipses.ts +47 -0
- package/tests/validation/compare/houses.ts +76 -0
- package/tests/validation/compare/positions.ts +104 -0
- package/tests/validation/compare/riseSet.ts +48 -0
- package/tests/validation/compare/roots.ts +90 -0
- package/tests/validation/compare/transits.ts +69 -0
- package/tests/validation/fixtures/astrolog-parity/core.ts +194 -0
- package/tests/validation/fixtures/eclipses/core.ts +14 -0
- package/tests/validation/fixtures/houses/core.ts +47 -0
- package/tests/validation/fixtures/positions/core.ts +159 -0
- package/tests/validation/fixtures/rise-set/core.ts +20 -0
- package/tests/validation/fixtures/roots/core.ts +47 -0
- package/tests/validation/fixtures/transits/core.ts +61 -0
- package/tests/validation/fixtures/transits/dst.ts +21 -0
- package/tests/validation/oracle.spec.ts +129 -0
- package/tests/validation/utils/denseRootOracle.ts +269 -0
- package/tests/validation/utils/fixtureTypes.ts +146 -0
- package/tests/validation/utils/report.ts +60 -0
- package/tests/validation/utils/tolerances.ts +23 -0
- package/tests/validation/validation.spec.ts +836 -0
- package/tools/color-picker.html +388 -0
- package/tsconfig.json +17 -0
- package/vitest.config.ts +31 -0
package/example-usage.md
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# Example Usage
|
|
2
|
+
|
|
3
|
+
This document shows how to use the Astro MCP server with an AI agent like Claude.
|
|
4
|
+
|
|
5
|
+
**Note:** The natal chart is stored in memory for the duration of your session. If you disconnect and reconnect, you'll need to call `set_natal_chart` again.
|
|
6
|
+
|
|
7
|
+
## Important: Time Handling
|
|
8
|
+
|
|
9
|
+
**Always provide birth time in LOCAL time** (not UTC):
|
|
10
|
+
- Use the time as it appeared on the clock at the birth location
|
|
11
|
+
- Specify the IANA timezone (e.g., `America/New_York`, not `EST`)
|
|
12
|
+
- The server will convert to UTC and handle DST automatically
|
|
13
|
+
- You'll receive verification feedback showing both local and UTC times
|
|
14
|
+
|
|
15
|
+
## Setting Up Your Wife's Natal Chart
|
|
16
|
+
|
|
17
|
+
First, she needs to provide her birth data. Ask your AI agent:
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
Please set my natal chart:
|
|
21
|
+
- Name: Jane
|
|
22
|
+
- Birth: January 15, 1985 at 14:30 (2:30 PM)
|
|
23
|
+
- Location: Los Angeles, CA (34.0522°N, 118.2437°W)
|
|
24
|
+
- Timezone: America/Los_Angeles
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
The agent will call `set_natal_chart` with:
|
|
28
|
+
```json
|
|
29
|
+
{
|
|
30
|
+
"name": "Jane",
|
|
31
|
+
"year": 1985,
|
|
32
|
+
"month": 1,
|
|
33
|
+
"day": 15,
|
|
34
|
+
"hour": 14,
|
|
35
|
+
"minute": 30,
|
|
36
|
+
"latitude": 34.0522,
|
|
37
|
+
"longitude": -118.2437,
|
|
38
|
+
"timezone": "America/Los_Angeles",
|
|
39
|
+
"house_system": "P"
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**Note:** Hour is in LOCAL time (14:30 = 2:30 PM). The server converts to UTC automatically.
|
|
44
|
+
|
|
45
|
+
The server responds with verification:
|
|
46
|
+
```
|
|
47
|
+
Natal chart saved for Jane
|
|
48
|
+
|
|
49
|
+
Birth Details:
|
|
50
|
+
- Local Time: 1/15/1985 14:30 (America/Los_Angeles)
|
|
51
|
+
- UTC Time: 1/15/1985 22:30 UTC
|
|
52
|
+
- Location: 34.05°N, -118.24°W
|
|
53
|
+
|
|
54
|
+
Chart Angles:
|
|
55
|
+
- Sun: 25° Capricorn
|
|
56
|
+
- Moon: 12° Gemini
|
|
57
|
+
- Ascendant: 8° Taurus
|
|
58
|
+
- MC: 15° Capricorn
|
|
59
|
+
|
|
60
|
+
House System: Placidus
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Daily Transit Queries
|
|
64
|
+
|
|
65
|
+
### Morning Check-In
|
|
66
|
+
"What are my transits for today?"
|
|
67
|
+
|
|
68
|
+
The agent will call:
|
|
69
|
+
- `get_daily_transits` - Current planetary positions
|
|
70
|
+
- `get_moon_transits` - Moon aspects to natal planets
|
|
71
|
+
- `get_personal_planet_transits` - Sun/Mercury/Venus/Mars aspects
|
|
72
|
+
- `get_outer_planet_transits` - Slower moving planets
|
|
73
|
+
|
|
74
|
+
### Specific Questions
|
|
75
|
+
|
|
76
|
+
**"When will the Moon conjunct my Venus be exact?"**
|
|
77
|
+
- Agent calls `get_exact_transit_times`
|
|
78
|
+
- Returns precise time when aspect is 0° orb
|
|
79
|
+
|
|
80
|
+
**"What transits are coming up this week?"**
|
|
81
|
+
- Agent calls `get_upcoming_transits` with `days: 7`
|
|
82
|
+
- Shows all transits approaching within 2° orb
|
|
83
|
+
|
|
84
|
+
**"Show me just the outer planet transits"**
|
|
85
|
+
- Agent calls `get_outer_planet_transits`
|
|
86
|
+
- Returns Jupiter, Saturn, Uranus, Neptune, Pluto aspects
|
|
87
|
+
|
|
88
|
+
## Sample Output
|
|
89
|
+
|
|
90
|
+
### Moon Transits
|
|
91
|
+
```
|
|
92
|
+
Moon Transits:
|
|
93
|
+
|
|
94
|
+
Moon conjunction Venus: 0.45° orb (applying) - Exact: 2026-03-27T03:24:15.000Z
|
|
95
|
+
Moon sextile Mars: 1.23° orb (separating)
|
|
96
|
+
Moon trine Jupiter: 2.87° orb (applying)
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Personal Planet Transits
|
|
100
|
+
```
|
|
101
|
+
Personal Planet Transits:
|
|
102
|
+
|
|
103
|
+
Sun square natal Moon: 0.89° orb (applying) - Exact: 2026-03-27T18:45:32.000Z
|
|
104
|
+
Venus trine natal Sun: 3.21° orb (separating)
|
|
105
|
+
Mars opposition natal Mercury: 5.67° orb (applying)
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Upcoming Transits (7 days)
|
|
109
|
+
```
|
|
110
|
+
Upcoming Transits (next 7 days):
|
|
111
|
+
|
|
112
|
+
Jupiter trine natal Venus: 1.45° orb (applying) - Exact: 2026-03-29T12:30:00.000Z
|
|
113
|
+
Saturn square natal Mars: 1.89° orb (applying) - Exact: 2026-04-01T08:15:45.000Z
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Understanding the Output
|
|
117
|
+
|
|
118
|
+
- **Orb**: How close the aspect is (0° = exact)
|
|
119
|
+
- **Applying**: Transit is getting closer to exact
|
|
120
|
+
- **Separating**: Transit is moving away from exact
|
|
121
|
+
- **Exact time**: When the aspect becomes 0° orb (only shown for transits within 2°)
|
|
122
|
+
|
|
123
|
+
## Tips for Your Wife
|
|
124
|
+
|
|
125
|
+
1. **Morning routine**: Check daily transits each morning
|
|
126
|
+
2. **Plan ahead**: Use `get_upcoming_transits` to see what's coming
|
|
127
|
+
3. **Track exact times**: Important transits show exact timing for planning
|
|
128
|
+
4. **Focus on what matters**:
|
|
129
|
+
- Moon transits change quickly (every few hours)
|
|
130
|
+
- Personal planets change daily/weekly
|
|
131
|
+
- Outer planets can last weeks/months
|
package/natal-chart.json
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "User Whole Sign",
|
|
3
|
+
"birthDate": {
|
|
4
|
+
"year": 1977,
|
|
5
|
+
"month": 10,
|
|
6
|
+
"day": 17,
|
|
7
|
+
"hour": 13,
|
|
8
|
+
"minute": 6
|
|
9
|
+
},
|
|
10
|
+
"location": {
|
|
11
|
+
"latitude": 40.7526,
|
|
12
|
+
"longitude": -80.3198,
|
|
13
|
+
"timezone": "America/New_York"
|
|
14
|
+
},
|
|
15
|
+
"planets": [
|
|
16
|
+
{
|
|
17
|
+
"planet": "Sun",
|
|
18
|
+
"longitude": 204.05218050976873,
|
|
19
|
+
"latitude": 0.0001615388556612532,
|
|
20
|
+
"distance": 0.9964210583337456,
|
|
21
|
+
"speed": 0.9928259050042711,
|
|
22
|
+
"sign": "Libra",
|
|
23
|
+
"degree": 24.052180509768732,
|
|
24
|
+
"isRetrograde": false
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"planet": "Moon",
|
|
28
|
+
"longitude": 267.7474069899507,
|
|
29
|
+
"latitude": 5.03828787700736,
|
|
30
|
+
"distance": 0.0024531797587498657,
|
|
31
|
+
"speed": 14.457512480190383,
|
|
32
|
+
"sign": "Sagittarius",
|
|
33
|
+
"degree": 27.74740698995072,
|
|
34
|
+
"isRetrograde": false
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"planet": "Mercury",
|
|
38
|
+
"longitude": 203.05615113717954,
|
|
39
|
+
"latitude": 0.956300075310156,
|
|
40
|
+
"distance": 1.4134856844175427,
|
|
41
|
+
"speed": 1.7001421021313727,
|
|
42
|
+
"sign": "Libra",
|
|
43
|
+
"degree": 23.05615113717954,
|
|
44
|
+
"isRetrograde": false
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"planet": "Venus",
|
|
48
|
+
"longitude": 180.59233174758765,
|
|
49
|
+
"latitude": 1.520411261036414,
|
|
50
|
+
"distance": 1.5124130040316783,
|
|
51
|
+
"speed": 1.2383468359522916,
|
|
52
|
+
"sign": "Libra",
|
|
53
|
+
"degree": 0.5923317475876502,
|
|
54
|
+
"isRetrograde": false
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"planet": "Mars",
|
|
58
|
+
"longitude": 115.83306761812116,
|
|
59
|
+
"latitude": 1.0377403010723354,
|
|
60
|
+
"distance": 1.1984622765651196,
|
|
61
|
+
"speed": 0.47310831677259674,
|
|
62
|
+
"sign": "Cancer",
|
|
63
|
+
"degree": 25.833067618121163,
|
|
64
|
+
"isRetrograde": false
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"planet": "Jupiter",
|
|
68
|
+
"longitude": 96.06324009530363,
|
|
69
|
+
"latitude": -0.3624170362523381,
|
|
70
|
+
"distance": 4.715321463223517,
|
|
71
|
+
"speed": 0.022806312817944503,
|
|
72
|
+
"sign": "Cancer",
|
|
73
|
+
"degree": 6.063240095303627,
|
|
74
|
+
"isRetrograde": false
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"planet": "Saturn",
|
|
78
|
+
"longitude": 147.9183963947238,
|
|
79
|
+
"latitude": 1.1514198531366935,
|
|
80
|
+
"distance": 9.71241768931636,
|
|
81
|
+
"speed": 0.08930814127132901,
|
|
82
|
+
"sign": "Leo",
|
|
83
|
+
"degree": 27.9183963947238,
|
|
84
|
+
"isRetrograde": false
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"planet": "Uranus",
|
|
88
|
+
"longitude": 220.99220136598956,
|
|
89
|
+
"latitude": 0.39006096397372564,
|
|
90
|
+
"distance": 19.547124554119833,
|
|
91
|
+
"speed": 0.06054899513110079,
|
|
92
|
+
"sign": "Scorpio",
|
|
93
|
+
"degree": 10.992201365989558,
|
|
94
|
+
"isRetrograde": false
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"planet": "Neptune",
|
|
98
|
+
"longitude": 254.1099953294147,
|
|
99
|
+
"latitude": 1.4392507913670756,
|
|
100
|
+
"distance": 30.91780788606139,
|
|
101
|
+
"speed": 0.026698768271311017,
|
|
102
|
+
"sign": "Sagittarius",
|
|
103
|
+
"degree": 14.109995329414687,
|
|
104
|
+
"isRetrograde": false
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"planet": "Pluto",
|
|
108
|
+
"longitude": 194.47902308697212,
|
|
109
|
+
"latitude": 16.530727897276424,
|
|
110
|
+
"distance": 31.37683977306858,
|
|
111
|
+
"speed": 0.038963569772553476,
|
|
112
|
+
"sign": "Libra",
|
|
113
|
+
"degree": 14.47902308697212,
|
|
114
|
+
"isRetrograde": false
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"planet": "North Node (Mean)",
|
|
118
|
+
"longitude": 194.5511103273211,
|
|
119
|
+
"latitude": 0,
|
|
120
|
+
"distance": 0.0025695552897999903,
|
|
121
|
+
"speed": -0.05293530033441037,
|
|
122
|
+
"sign": "Libra",
|
|
123
|
+
"degree": 14.551110327321112,
|
|
124
|
+
"isRetrograde": true
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"planet": "North Node (True)",
|
|
128
|
+
"longitude": 195.2274831010368,
|
|
129
|
+
"latitude": 0,
|
|
130
|
+
"distance": 0.0024556133228558225,
|
|
131
|
+
"speed": -0.013109185725915731,
|
|
132
|
+
"sign": "Libra",
|
|
133
|
+
"degree": 15.227483101036796,
|
|
134
|
+
"isRetrograde": true
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
"planet": "Chiron",
|
|
138
|
+
"longitude": 33.86707264166279,
|
|
139
|
+
"latitude": -0.5386594883172258,
|
|
140
|
+
"distance": 16.867648288381556,
|
|
141
|
+
"speed": -0.046728100146171576,
|
|
142
|
+
"sign": "Taurus",
|
|
143
|
+
"degree": 3.867072641662787,
|
|
144
|
+
"isRetrograde": true
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
"planet": "Ceres",
|
|
148
|
+
"longitude": 225.17925484526404,
|
|
149
|
+
"latitude": 3.722322777056521,
|
|
150
|
+
"distance": 3.6128220583215915,
|
|
151
|
+
"speed": 0.42320521586905213,
|
|
152
|
+
"sign": "Scorpio",
|
|
153
|
+
"degree": 15.17925484526404,
|
|
154
|
+
"isRetrograde": false
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"planet": "Pallas",
|
|
158
|
+
"longitude": 204.86164458449048,
|
|
159
|
+
"latitude": 14.672306160015758,
|
|
160
|
+
"distance": 3.548347696867575,
|
|
161
|
+
"speed": 0.4450325558858604,
|
|
162
|
+
"sign": "Libra",
|
|
163
|
+
"degree": 24.861644584490477,
|
|
164
|
+
"isRetrograde": false
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
"planet": "Juno",
|
|
168
|
+
"longitude": 243.42276981356122,
|
|
169
|
+
"latitude": 10.664052131434042,
|
|
170
|
+
"distance": 3.9911632546316698,
|
|
171
|
+
"speed": 0.313194206647786,
|
|
172
|
+
"sign": "Sagittarius",
|
|
173
|
+
"degree": 3.4227698135612172,
|
|
174
|
+
"isRetrograde": false
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
"planet": "Vesta",
|
|
178
|
+
"longitude": 188.4269007577168,
|
|
179
|
+
"latitude": 4.9410232440203075,
|
|
180
|
+
"distance": 3.2207217522128566,
|
|
181
|
+
"speed": 0.5021548471029085,
|
|
182
|
+
"sign": "Libra",
|
|
183
|
+
"degree": 8.426900757716794,
|
|
184
|
+
"isRetrograde": false
|
|
185
|
+
}
|
|
186
|
+
]
|
|
187
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ether-to-astro",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Local-first astrology toolkit with a CLI (e2a) and MCP server (e2a-mcp) for charts, transits, rendering, and agent workflows.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": ">=20"
|
|
9
|
+
},
|
|
10
|
+
"bin": {
|
|
11
|
+
"e2a-mcp": "dist/loader.js",
|
|
12
|
+
"e2a": "dist/cli.js"
|
|
13
|
+
},
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsc",
|
|
16
|
+
"dev": "tsc --watch",
|
|
17
|
+
"dev:watch": "tsx watch src/loader.ts",
|
|
18
|
+
"start": "node dist/loader.js",
|
|
19
|
+
"start:cli": "node dist/cli.js",
|
|
20
|
+
"postinstall": "node scripts/download-ephemeris.js",
|
|
21
|
+
"test": "vitest tests/unit",
|
|
22
|
+
"validate:astro": "vitest run tests/validation",
|
|
23
|
+
"test:ui": "vitest --ui",
|
|
24
|
+
"test:coverage": "vitest run tests/unit --coverage",
|
|
25
|
+
"calculate-expected": "tsx tests/fixtures/calculate-expected.ts",
|
|
26
|
+
"quality:gate": "npm run build && npm run lint && npm test -- --run",
|
|
27
|
+
"lint": "biome check .",
|
|
28
|
+
"lint:fix": "biome check --write .",
|
|
29
|
+
"format": "biome format --write ."
|
|
30
|
+
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"mcp",
|
|
33
|
+
"astrology",
|
|
34
|
+
"swiss-ephemeris",
|
|
35
|
+
"transits"
|
|
36
|
+
],
|
|
37
|
+
"author": "",
|
|
38
|
+
"license": "AGPL-3.0-or-later",
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"@astrodraw/astrochart": "^3.0.2",
|
|
41
|
+
"@js-temporal/polyfill": "^0.5.1",
|
|
42
|
+
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
43
|
+
"@std/datetime": "npm:@jsr/std__datetime@^0.225.7",
|
|
44
|
+
"commander": "^14.0.3",
|
|
45
|
+
"picocolors": "^1.1.1",
|
|
46
|
+
"sharp": "^0.34.5",
|
|
47
|
+
"sweph": "2.10.3-b-1"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@biomejs/biome": "^2.4.9",
|
|
51
|
+
"@types/jsdom": "^28.0.1",
|
|
52
|
+
"@types/node": "^20.0.0",
|
|
53
|
+
"@vitest/coverage-v8": "^4.1.2",
|
|
54
|
+
"@vitest/ui": "^4.1.2",
|
|
55
|
+
"happy-dom": "^20.8.9",
|
|
56
|
+
"jsdom": "^29.0.1",
|
|
57
|
+
"tsx": "^4.21.0",
|
|
58
|
+
"typescript": "^5.0.0",
|
|
59
|
+
"vitest": "^4.1.2"
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { access, mkdir, writeFile } from 'node:fs/promises';
|
|
4
|
+
import { dirname, join } from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
|
|
7
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
const DATA_DIR = join(__dirname, '..', 'data', 'ephemeris');
|
|
9
|
+
|
|
10
|
+
// Environment variable controls which version to download
|
|
11
|
+
// EPHEMERIS_VERSION=short (600 years, ~2MB) | long (6000 years, ~5MB, DEFAULT) | moshier (none, use built-in)
|
|
12
|
+
const VERSION = (process.env.EPHEMERIS_VERSION || 'long').toLowerCase();
|
|
13
|
+
|
|
14
|
+
const SHORT_FILES = [
|
|
15
|
+
{ name: 'sepl_18.se1', desc: 'Main planets (Sun-Pluto) [600yr]' },
|
|
16
|
+
{ name: 'semo_18.se1', desc: 'High-precision Moon [600yr]' },
|
|
17
|
+
{ name: 'seas_18.se1', desc: 'Asteroids [600yr]' },
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
const LONG_FILES = [
|
|
21
|
+
{ name: 'sepl_18.se1', desc: 'Main planets (Sun-Pluto) [6000yr]' },
|
|
22
|
+
{ name: 'semo_18.se1', desc: 'High-precision Moon [6000yr]' },
|
|
23
|
+
{ name: 'seas_18.se1', desc: 'Asteroids [6000yr]' },
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
const BASE_URL_SHORT = 'https://raw.githubusercontent.com/aloistr/swisseph/master/ephe';
|
|
27
|
+
const BASE_URL_LONG = 'https://raw.githubusercontent.com/aloistr/swisseph/master/ephe';
|
|
28
|
+
|
|
29
|
+
async function fileExists(path) {
|
|
30
|
+
try {
|
|
31
|
+
await access(path);
|
|
32
|
+
return true;
|
|
33
|
+
} catch {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function downloadFile(filename, description, baseUrl) {
|
|
39
|
+
const filePath = join(DATA_DIR, filename);
|
|
40
|
+
|
|
41
|
+
if (await fileExists(filePath)) {
|
|
42
|
+
console.log(`✓ ${description} already exists`);
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const url = `${baseUrl}/${filename}`;
|
|
47
|
+
console.log(`Downloading ${description}...`);
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
const response = await fetch(url);
|
|
51
|
+
if (!response.ok) {
|
|
52
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const buffer = await response.arrayBuffer();
|
|
56
|
+
await writeFile(filePath, Buffer.from(buffer));
|
|
57
|
+
|
|
58
|
+
const sizeMB = (buffer.byteLength / 1024 / 1024).toFixed(2);
|
|
59
|
+
console.log(`✓ Downloaded ${description} (${sizeMB}MB)`);
|
|
60
|
+
return true;
|
|
61
|
+
} catch (error) {
|
|
62
|
+
console.warn(`⚠ Failed to download ${description}: ${error.message}`);
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async function main() {
|
|
68
|
+
console.log(`Setting up Swiss Ephemeris data files (${VERSION} version)...\n`);
|
|
69
|
+
|
|
70
|
+
// Moshier mode - skip downloads entirely
|
|
71
|
+
if (VERSION === 'moshier') {
|
|
72
|
+
console.log('✓ Using Moshier ephemeris (built-in approximation, no downloads)');
|
|
73
|
+
console.log(' Lower precision but works offline\n');
|
|
74
|
+
process.exit(0);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Determine which files to download
|
|
78
|
+
const FILES = VERSION === 'short' ? SHORT_FILES : LONG_FILES;
|
|
79
|
+
const BASE_URL = VERSION === 'short' ? BASE_URL_SHORT : BASE_URL_LONG;
|
|
80
|
+
|
|
81
|
+
if (!['short', 'long'].includes(VERSION)) {
|
|
82
|
+
console.warn(`⚠ Unknown EPHEMERIS_VERSION: "${VERSION}"`);
|
|
83
|
+
console.warn('Valid options: short, long (default), moshier');
|
|
84
|
+
console.warn('Defaulting to long version...\n');
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
try {
|
|
88
|
+
await mkdir(DATA_DIR, { recursive: true });
|
|
89
|
+
} catch (error) {
|
|
90
|
+
console.error(`Failed to create data directory: ${error.message}`);
|
|
91
|
+
process.exit(0); // Fail silently - will use Moshier fallback
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
let successCount = 0;
|
|
95
|
+
for (const file of FILES) {
|
|
96
|
+
const success = await downloadFile(file.name, file.desc, BASE_URL);
|
|
97
|
+
if (success) successCount++;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
console.log(`\n${successCount}/${FILES.length} ephemeris files ready`);
|
|
101
|
+
|
|
102
|
+
if (successCount === 0) {
|
|
103
|
+
console.warn('\n⚠ Warning: No ephemeris files downloaded.');
|
|
104
|
+
console.warn('The server will use Moshier ephemeris (lower precision).');
|
|
105
|
+
console.warn('You can manually download files from:');
|
|
106
|
+
console.warn('https://github.com/aloistr/swisseph/tree/master/ephe\n');
|
|
107
|
+
} else {
|
|
108
|
+
const rangeDesc = VERSION === 'short' ? '1800-2400 AD' : '3000 BC - 3000 AD';
|
|
109
|
+
console.log(`Date range: ${rangeDesc}\n`);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
process.exit(0);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
main();
|
package/setup.sh
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
echo "Setting up Astro MCP Server..."
|
|
4
|
+
|
|
5
|
+
echo "Installing npm dependencies..."
|
|
6
|
+
npm install
|
|
7
|
+
|
|
8
|
+
echo "Building TypeScript..."
|
|
9
|
+
npm run build
|
|
10
|
+
|
|
11
|
+
echo ""
|
|
12
|
+
echo "✅ Setup complete!"
|
|
13
|
+
echo ""
|
|
14
|
+
echo "The server uses WebAssembly Swiss Ephemeris - no data files needed!"
|
|
15
|
+
echo ""
|
|
16
|
+
echo "Next steps:"
|
|
17
|
+
echo "1. Add this server to your MCP settings"
|
|
18
|
+
echo "2. Use set_natal_chart to store birth data"
|
|
19
|
+
echo "3. Query transits with your AI agent"
|
|
20
|
+
echo ""
|
|
21
|
+
echo "See README.md for detailed usage instructions."
|