@openephemeris/mcp-server 4.16.0 → 4.17.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/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,24 @@ Version numbering follows [Semantic Versioning](https://semver.org/).
|
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
+
## [4.17.0] — 2026-09-24
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- **Transit timelines show when each transit starts and ends.** `explore_transit_timeline` now asks
|
|
14
|
+
for orb windows (new `orb_deg` parameter, default 1°): every exact hit carries the in-orb window it
|
|
15
|
+
belongs to — the date the transit comes into orb and the date it leaves — and "pass 2 of 3" when a
|
|
16
|
+
retrograde brings the planet back over the same point without leaving the orb. Transits already in
|
|
17
|
+
orb at the start of the range are listed with whether they are applying or separating. The
|
|
18
|
+
interactive timeline shows the window on each card.
|
|
19
|
+
- **Two new API capabilities reachable through `dev_read_api`:** orb windows on
|
|
20
|
+
`POST /predictive/transits/search` (`orb_deg`, `aspect_orbs`, `natal_points`, `aspects`) and the new
|
|
21
|
+
`POST /human-design/transit-timeline` — every gate (and line) a transiting planet enters and leaves
|
|
22
|
+
over a date range, and when a transit completes one of your channels. 121 public endpoints.
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
- **`dev_read_api` now reaches three endpoints it was missing:** `/ephemeris/draconic`,
|
|
26
|
+
`/ephemeris/prenatal-lunation` and `/predictive/primary-directions` (124 allowlisted operations).
|
|
27
|
+
|
|
10
28
|
## [4.16.0] — 2026-09-21
|
|
11
29
|
|
|
12
30
|
### Changed
|
package/README.md
CHANGED
|
@@ -490,8 +490,8 @@ When you update the MCP server logic (handlers, bug fixes, hardening), you shoul
|
|
|
490
490
|
|
|
491
491
|
Generated by `npm run sync:readme` from `config/dev-allowlist.json` and the live tool registry.
|
|
492
492
|
|
|
493
|
-
- Allowlisted operations: **
|
|
494
|
-
- Methods: `GET=44`, `POST=
|
|
493
|
+
- Allowlisted operations: **124**
|
|
494
|
+
- Methods: `GET=44`, `POST=80`, `PUT=0`, `PATCH=0`, `DELETE=0`
|
|
495
495
|
- Registered tools (`OPENEPHEMERIS_PROFILE=dev`): **92**
|
|
496
496
|
- Typed tools: `account_usage`, `acg_hits`, `acg_power_lines`, `auth_login`, `auth_logout`, `auth_status`, `bazi_annual_pillar`, `bazi_chart`, `bazi_compatibility`, `bazi_element_balance`, `bazi_luck_pillars`, `bazi_recalculate`, `bazi_ten_gods`, `bi_wheel_on_cross_aspect_click`, `bi_wheel_on_house_click`, `bi_wheel_on_planet_click`, `bi_wheel_recalculate`, `bi_wheel_synopsis`, `bodygraph_recalculate`, `chart_wheel_on_aspect_click`, `chart_wheel_on_house_click`, `chart_wheel_on_planet_click`, `chart_wheel_recalculate`, `chinese_bazi`, `electional_angle_crossings`, `electional_aspect_search`, `electional_moment_analysis`, `electional_station_tracker`, `ephemeris_angles_points`, `ephemeris_aspect_check`, `ephemeris_bi_wheel`, `ephemeris_chart_wheel`, `ephemeris_composite`, `ephemeris_composite_midpoint`, `ephemeris_dignities`, `ephemeris_electional`, `ephemeris_fixed_stars`, `ephemeris_hermetic_lots`, `ephemeris_house_cusps`, `ephemeris_lunar_return`, `ephemeris_midpoints`, `ephemeris_moon_phase`, `ephemeris_natal_batch`, `ephemeris_natal_chart`, `ephemeris_natal_transits`, `ephemeris_next_eclipse`, `ephemeris_next_lunar_phase`, `ephemeris_overlay`, `ephemeris_planet_position`, `ephemeris_planetary_return`, `ephemeris_progressed_chart`, `ephemeris_relocation`, `ephemeris_retrograde_status`, `ephemeris_solar_return`, `ephemeris_synastry`, `ephemeris_transits`, `explore_bazi_chart`, `explore_bi_wheel`, `explore_human_design`, `explore_human_design_connection`, `explore_human_design_transit`, `explore_moon_phase`, `explore_natal_chart`, `explore_transit_timeline`, `explore_vedic_chart`, `hd_on_center_click`, `hd_on_channel_click`, `hd_on_connection_channel_click`, `hd_on_gate_click`, `hd_on_planet_click`, `hd_on_transit_channel_click`, `hd_on_variable_click`, `hd_opposition`, `hd_planetary_return`, `human_design_bodygraph`, `human_design_chart`, `human_design_composite`, `human_design_penta`, `location_search`, `moon_phase_recalculate`, `timezone_resolve`, `vedic_chart`, `vedic_chart_recalculate`, `venus_eight_year_star`, `venus_elongations`, `venus_phase`, `venus_star_points`, `venus_star_points_conjunctions`, `venus_stations`
|
|
497
497
|
- Generic tools: `dev_list_allowed`, `dev_read_api`, `dev_write_api`
|
|
@@ -507,11 +507,11 @@ Generated by `npm run sync:readme` from `config/dev-allowlist.json` and the live
|
|
|
507
507
|
| `comparative` | 5 | `POST /comparative/composite`, `POST /comparative/composite/midpoint` |
|
|
508
508
|
| `eclipse` | 6 | `GET /eclipse/besselian-elements`, `GET /eclipse/lunar/global` |
|
|
509
509
|
| `electional` | 6 | `GET /electional/angle-crossings`, `GET /electional/aspect-search` |
|
|
510
|
-
| `ephemeris` |
|
|
510
|
+
| `ephemeris` | 38 | `GET /ephemeris/agro/calendar`, `GET /ephemeris/agro/daily` |
|
|
511
511
|
| `health` | 2 | `GET /health`, `GET /health/detailed` |
|
|
512
|
-
| `human-design` |
|
|
512
|
+
| `human-design` | 9 | `POST /human-design/chart`, `POST /human-design/composite` |
|
|
513
513
|
| `location` | 2 | `GET /location/autocomplete`, `GET /location/reverse` |
|
|
514
|
-
| `predictive` |
|
|
514
|
+
| `predictive` | 11 | `POST /predictive/primary-directions`, `POST /predictive/returns` |
|
|
515
515
|
| `root` | 1 | `GET /` |
|
|
516
516
|
| `tidal` | 2 | `GET /tidal/forcing`, `GET /tidal/forcing/deep-time` |
|
|
517
517
|
| `time` | 6 | `GET /time/delta-t`, `GET /time/equation-of-time` |
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": "astromcp-dev-allowlist-v1",
|
|
3
3
|
"description": "Allowlist derived from the Go sidecar openapi.json. Every entry in allow[] corresponds to a real Go endpoint. Run 'npm run check:dev-allowlist' to validate freshness.",
|
|
4
|
-
"generated_from": "C:\\src\\openephemeris\\.claude\\worktrees\\
|
|
4
|
+
"generated_from": "C:\\src\\openephemeris\\.claude\\worktrees\\adoring-rhodes-871fd7\\apps\\api\\go-sidecar\\openapi.json",
|
|
5
5
|
"deny": {
|
|
6
6
|
"path_prefixes": [
|
|
7
7
|
"/auth",
|
|
@@ -235,6 +235,10 @@
|
|
|
235
235
|
"method": "POST",
|
|
236
236
|
"path": "/ephemeris/dispositor-tree"
|
|
237
237
|
},
|
|
238
|
+
{
|
|
239
|
+
"method": "POST",
|
|
240
|
+
"path": "/ephemeris/draconic"
|
|
241
|
+
},
|
|
238
242
|
{
|
|
239
243
|
"method": "POST",
|
|
240
244
|
"path": "/ephemeris/fixed-stars"
|
|
@@ -291,6 +295,10 @@
|
|
|
291
295
|
"method": "POST",
|
|
292
296
|
"path": "/ephemeris/planet-position"
|
|
293
297
|
},
|
|
298
|
+
{
|
|
299
|
+
"method": "POST",
|
|
300
|
+
"path": "/ephemeris/prenatal-lunation"
|
|
301
|
+
},
|
|
294
302
|
{
|
|
295
303
|
"method": "POST",
|
|
296
304
|
"path": "/ephemeris/progressed"
|
|
@@ -383,6 +391,10 @@
|
|
|
383
391
|
"method": "POST",
|
|
384
392
|
"path": "/human-design/transit-chart"
|
|
385
393
|
},
|
|
394
|
+
{
|
|
395
|
+
"method": "POST",
|
|
396
|
+
"path": "/human-design/transit-timeline"
|
|
397
|
+
},
|
|
386
398
|
{
|
|
387
399
|
"method": "POST",
|
|
388
400
|
"path": "/human-design/transit"
|
|
@@ -395,6 +407,10 @@
|
|
|
395
407
|
"method": "GET",
|
|
396
408
|
"path": "/location/reverse"
|
|
397
409
|
},
|
|
410
|
+
{
|
|
411
|
+
"method": "POST",
|
|
412
|
+
"path": "/predictive/primary-directions"
|
|
413
|
+
},
|
|
398
414
|
{
|
|
399
415
|
"method": "POST",
|
|
400
416
|
"path": "/predictive/returns/lunar"
|
|
@@ -496,8 +512,8 @@
|
|
|
496
512
|
"path": "/visualization/chart-wheel"
|
|
497
513
|
}
|
|
498
514
|
],
|
|
499
|
-
"last_generated_at": "2026-
|
|
500
|
-
"openapi_sha256": "
|
|
515
|
+
"last_generated_at": "2026-09-24T18:29:22.473Z",
|
|
516
|
+
"openapi_sha256": "f5927cecddb0f8629f7c94d380ca878e6780bc491f85490bacb2508e1b721b3d",
|
|
501
517
|
"candidates_get": [
|
|
502
518
|
{
|
|
503
519
|
"method": "GET",
|
|
@@ -893,22 +909,6 @@
|
|
|
893
909
|
],
|
|
894
910
|
"operationId": "declination_lines_acg_declination_lines_post"
|
|
895
911
|
},
|
|
896
|
-
{
|
|
897
|
-
"method": "POST",
|
|
898
|
-
"path": "/acg/features",
|
|
899
|
-
"tags": [
|
|
900
|
-
"ACG"
|
|
901
|
-
],
|
|
902
|
-
"operationId": "features_acg_features_post"
|
|
903
|
-
},
|
|
904
|
-
{
|
|
905
|
-
"method": "POST",
|
|
906
|
-
"path": "/acg/heatmap/composite",
|
|
907
|
-
"tags": [
|
|
908
|
-
"Astrocartography"
|
|
909
|
-
],
|
|
910
|
-
"operationId": "AcgHeatmapCompositeAcgHeatmapCompositePost"
|
|
911
|
-
},
|
|
912
912
|
{
|
|
913
913
|
"method": "POST",
|
|
914
914
|
"path": "/acg/hermetic-lines",
|
|
@@ -1341,6 +1341,14 @@
|
|
|
1341
1341
|
],
|
|
1342
1342
|
"operationId": "human_design_transit_chart_human_design_transit_chart_post"
|
|
1343
1343
|
},
|
|
1344
|
+
{
|
|
1345
|
+
"method": "POST",
|
|
1346
|
+
"path": "/human-design/transit-timeline",
|
|
1347
|
+
"tags": [
|
|
1348
|
+
"Human Design"
|
|
1349
|
+
],
|
|
1350
|
+
"operationId": "human_design_transit_timeline_human_design_transit_timeline_post"
|
|
1351
|
+
},
|
|
1344
1352
|
{
|
|
1345
1353
|
"method": "POST",
|
|
1346
1354
|
"path": "/human-design/transit",
|
|
@@ -1538,6 +1546,7 @@
|
|
|
1538
1546
|
"Non-GET allowlisted: POST /ephemeris/declinations",
|
|
1539
1547
|
"Non-GET allowlisted: POST /ephemeris/dignities",
|
|
1540
1548
|
"Non-GET allowlisted: POST /ephemeris/dispositor-tree",
|
|
1549
|
+
"Non-GET allowlisted: POST /ephemeris/draconic",
|
|
1541
1550
|
"Non-GET allowlisted: POST /ephemeris/fixed-stars",
|
|
1542
1551
|
"Non-GET allowlisted: POST /ephemeris/harmonics",
|
|
1543
1552
|
"Non-GET allowlisted: POST /ephemeris/hermetic-lots",
|
|
@@ -1547,6 +1556,7 @@
|
|
|
1547
1556
|
"Non-GET allowlisted: POST /ephemeris/natal-chart",
|
|
1548
1557
|
"Non-GET allowlisted: POST /ephemeris/natal/batch",
|
|
1549
1558
|
"Non-GET allowlisted: POST /ephemeris/planet-position",
|
|
1559
|
+
"Non-GET allowlisted: POST /ephemeris/prenatal-lunation",
|
|
1550
1560
|
"Non-GET allowlisted: POST /ephemeris/progressed",
|
|
1551
1561
|
"Non-GET allowlisted: POST /ephemeris/relocation",
|
|
1552
1562
|
"Non-GET allowlisted: POST /ephemeris/retrograde-status",
|
|
@@ -1563,7 +1573,9 @@
|
|
|
1563
1573
|
"Non-GET allowlisted: POST /human-design/cycles/solar-return",
|
|
1564
1574
|
"Non-GET allowlisted: POST /human-design/penta",
|
|
1565
1575
|
"Non-GET allowlisted: POST /human-design/transit-chart",
|
|
1576
|
+
"Non-GET allowlisted: POST /human-design/transit-timeline",
|
|
1566
1577
|
"Non-GET allowlisted: POST /human-design/transit",
|
|
1578
|
+
"Non-GET allowlisted: POST /predictive/primary-directions",
|
|
1567
1579
|
"Non-GET allowlisted: POST /predictive/returns/lunar",
|
|
1568
1580
|
"Non-GET allowlisted: POST /predictive/returns/solar",
|
|
1569
1581
|
"Non-GET allowlisted: POST /predictive/returns",
|
|
@@ -8,6 +8,9 @@
|
|
|
8
8
|
* chart to extract real planetary longitudes, searches predictive transits
|
|
9
9
|
* against those targets, then flattens the (planet@target → hits) result map
|
|
10
10
|
* into a single chronological array the iframe renders as a vertical timeline.
|
|
11
|
+
* The search asks for orb windows (orb_deg) too, so every exact hit carries the
|
|
12
|
+
* in-orb window it belongs to — when the transit starts and ends, and which
|
|
13
|
+
* pass it is when a retrograde brings the planet back over the same point.
|
|
11
14
|
*
|
|
12
15
|
* Also exports resource helpers (getTransitTimelineBundle, etc.) for use in
|
|
13
16
|
* index.ts and server-sse.ts.
|
|
@@ -8,6 +8,9 @@
|
|
|
8
8
|
* chart to extract real planetary longitudes, searches predictive transits
|
|
9
9
|
* against those targets, then flattens the (planet@target → hits) result map
|
|
10
10
|
* into a single chronological array the iframe renders as a vertical timeline.
|
|
11
|
+
* The search asks for orb windows (orb_deg) too, so every exact hit carries the
|
|
12
|
+
* in-orb window it belongs to — when the transit starts and ends, and which
|
|
13
|
+
* pass it is when a retrograde brings the planet back over the same point.
|
|
11
14
|
*
|
|
12
15
|
* Also exports resource helpers (getTransitTimelineBundle, etc.) for use in
|
|
13
16
|
* index.ts and server-sse.ts.
|
|
@@ -67,18 +70,32 @@ function normDeg(d) {
|
|
|
67
70
|
return ((d % 360) + 360) % 360;
|
|
68
71
|
}
|
|
69
72
|
// ── Summary builder ──────────────────────────────────────────────────────────
|
|
70
|
-
function
|
|
73
|
+
function shortDate(iso) {
|
|
74
|
+
return iso ? new Date(iso).toISOString().slice(0, 10) : "?";
|
|
75
|
+
}
|
|
76
|
+
function buildSummary(transits, windows, aspectLabel, orbDeg, win) {
|
|
77
|
+
const active = windows.filter((w) => w.phase_at_start);
|
|
78
|
+
const activeLines = active.slice(0, 6).map((w) => " • " + w.planet_name + " " + (w.aspect ?? aspectLabel) + (w.natal_point ? " natal " + w.natal_point : "") +
|
|
79
|
+
" — " + w.phase_at_start + ", " + (Math.round((w.orb_at_start ?? 0) * 100) / 100) + "° from exact, in orb until " +
|
|
80
|
+
shortDate(w.leave));
|
|
81
|
+
const activeBlock = activeLines.length
|
|
82
|
+
? "\n\nAlready in orb (" + orbDeg + "°) at the start:\n" + activeLines.join("\n")
|
|
83
|
+
: "";
|
|
71
84
|
if (transits.length === 0) {
|
|
72
|
-
return "**Transit Timeline** — no exact transit hits matched the search window and criteria.";
|
|
85
|
+
return "**Transit Timeline** — no exact transit hits matched the search window and criteria." + activeBlock;
|
|
73
86
|
}
|
|
74
87
|
const planets = [...new Set(transits.map((t) => t.planet_name).filter(Boolean))];
|
|
75
88
|
const lines = transits.slice(0, 8).map((t) => {
|
|
76
89
|
const asp = t.aspect ?? aspectLabel;
|
|
77
90
|
const natal = t.natal_point ? " natal " + t.natal_point : "";
|
|
78
91
|
const when = new Date(t.date).toISOString().slice(0, 10);
|
|
92
|
+
const passes = t.pass_count > 1 ? ", pass " + t.pass_index + " of " + t.pass_count : "";
|
|
93
|
+
const inOrb = t.window_start !== undefined
|
|
94
|
+
? " — in orb " + shortDate(t.window_start) + " → " + shortDate(t.window_end) + passes
|
|
95
|
+
: "";
|
|
79
96
|
return " • " + when + " — " + t.planet_name + " " + asp + natal +
|
|
80
97
|
(t.zodiac_sign ? " (" + (t.zodiac_degree ?? 0) + "° " + t.zodiac_sign + ")" : "") +
|
|
81
|
-
(t.is_retrograde ? " ℞" : "");
|
|
98
|
+
(t.is_retrograde ? " ℞" : "") + inOrb;
|
|
82
99
|
});
|
|
83
100
|
let summary = "**Transit Timeline** — " + transits.length + (transits.length === 1 ? " event" : " events") +
|
|
84
101
|
" from " + win.start_date + " to " + win.end_date +
|
|
@@ -86,6 +103,7 @@ function buildSummary(transits, aspectLabel, win) {
|
|
|
86
103
|
lines.join("\n");
|
|
87
104
|
if (transits.length > 8)
|
|
88
105
|
summary += "\n … and " + (transits.length - 8) + " more.";
|
|
106
|
+
summary += activeBlock;
|
|
89
107
|
summary += "\n\nClick any transit for details and interpretation.";
|
|
90
108
|
return summary;
|
|
91
109
|
}
|
|
@@ -97,7 +115,9 @@ registerTool({
|
|
|
97
115
|
"astrologically for me in 2027' — a forecast they should SEE. Returns an interactive, " +
|
|
98
116
|
"date-ordered timeline (inline in Claude and ChatGPT; text summary elsewhere) of exact transit " +
|
|
99
117
|
"hits grouped by month — transiting planet glyph, the natal point it contacts, the aspect, zodiac " +
|
|
100
|
-
"position and retrograde markers — each clickable for a focused interpretation
|
|
118
|
+
"position and retrograde markers — each clickable for a focused interpretation. Every hit carries its " +
|
|
119
|
+
"in-orb window (when the transit starts and ends, and which pass it is when a retrograde repeats it), " +
|
|
120
|
+
"and transits already in orb at the start are listed with applying/separating.\n\n" +
|
|
101
121
|
"ASPECT ANGLES: 0 = conjunction/return (default), 180 = opposition, 90 = square, 120 = trine, 60 " +
|
|
102
122
|
"= sextile. EFFICIENCY: specify transiting_planets and natal_points to keep compute fast. DEFAULT " +
|
|
103
123
|
"natal_points: sun, moon, mercury, venus, mars, jupiter, saturn. SEARCH RANGE LIMITS: " +
|
|
@@ -127,6 +147,10 @@ registerTool({
|
|
|
127
147
|
type: "number",
|
|
128
148
|
description: "Aspect angle in degrees. 0 = conjunction/return (default), 180 = opposition, 90 = square, 120 = trine, 60 = sextile.",
|
|
129
149
|
},
|
|
150
|
+
orb_deg: {
|
|
151
|
+
type: "number",
|
|
152
|
+
description: "Orb in degrees that defines when a transit starts and ends (the in-orb window around each exact hit). Default 1. Greater than 0, at most 15.",
|
|
153
|
+
},
|
|
130
154
|
},
|
|
131
155
|
required: ["natal_datetime", "natal_latitude", "natal_longitude", "start_date", "end_date"],
|
|
132
156
|
additionalProperties: false,
|
|
@@ -222,10 +246,12 @@ registerTool({
|
|
|
222
246
|
let endStr = args.end_date;
|
|
223
247
|
if (/^\d{4}-\d{2}-\d{2}$/.test(endStr))
|
|
224
248
|
endStr += "T23:59:59Z";
|
|
249
|
+
const orbDeg = typeof args.orb_deg === "number" && args.orb_deg > 0 ? Math.min(args.orb_deg, 15) : 1;
|
|
225
250
|
const transitBody = {
|
|
226
251
|
start_date: startStr,
|
|
227
252
|
end_date: endStr,
|
|
228
253
|
target_degrees: effectiveTargets,
|
|
254
|
+
orb_deg: orbDeg,
|
|
229
255
|
};
|
|
230
256
|
if (args.transiting_planets)
|
|
231
257
|
transitBody.planet_names = args.transiting_planets;
|
|
@@ -278,10 +304,53 @@ registerTool({
|
|
|
278
304
|
}
|
|
279
305
|
}
|
|
280
306
|
transits.sort((a, b) => new Date(a.date).getTime() - new Date(b.date).getTime());
|
|
307
|
+
// ── Step 5: orb windows → attach each exact hit to its window ────────────
|
|
308
|
+
// A window groups every pass the planet makes without leaving the orb, so
|
|
309
|
+
// a retrograde triple pass is one window with three exacts. Hits are
|
|
310
|
+
// matched to windows by planet, target degree and exact time.
|
|
311
|
+
const rawWindows = Array.isArray(transitResult?.windows) ? transitResult.windows : [];
|
|
312
|
+
const windows = rawWindows.map((w) => {
|
|
313
|
+
const target = typeof w?.target_longitude === "number" ? w.target_longitude : null;
|
|
314
|
+
return {
|
|
315
|
+
planet: String(w?.planet_name ?? "").toLowerCase(),
|
|
316
|
+
planet_name: String(w?.planet_name ?? ""),
|
|
317
|
+
natal_point: target != null ? nearestPoint(target) : "",
|
|
318
|
+
aspect: aspectLabel,
|
|
319
|
+
target_longitude: target,
|
|
320
|
+
orb_deg: w?.orb_deg ?? orbDeg,
|
|
321
|
+
enter: w?.enter ?? null,
|
|
322
|
+
leave: w?.leave ?? null,
|
|
323
|
+
exacts: Array.isArray(w?.exacts)
|
|
324
|
+
? w.exacts.map((e) => ({ time: e?.time, is_retrograde: Boolean(e?.is_retrograde) }))
|
|
325
|
+
: [],
|
|
326
|
+
duration_days: w?.duration_days ?? null,
|
|
327
|
+
phase_at_start: w?.phase_at_start ?? null,
|
|
328
|
+
orb_at_start: w?.orb_at_start ?? null,
|
|
329
|
+
};
|
|
330
|
+
});
|
|
331
|
+
for (const t of transits) {
|
|
332
|
+
const hitMs = new Date(t.date).getTime();
|
|
333
|
+
for (const w of windows) {
|
|
334
|
+
if (w.planet_name !== t.planet_name || w.target_longitude == null || t.target_longitude == null)
|
|
335
|
+
continue;
|
|
336
|
+
if (Math.abs(w.target_longitude - t.target_longitude) > 0.01)
|
|
337
|
+
continue;
|
|
338
|
+
const idx = w.exacts.findIndex((e) => Math.abs(new Date(e.time).getTime() - hitMs) <= 60_000);
|
|
339
|
+
if (idx < 0)
|
|
340
|
+
continue;
|
|
341
|
+
t.window_start = w.enter;
|
|
342
|
+
t.window_end = w.leave;
|
|
343
|
+
t.pass_index = idx + 1;
|
|
344
|
+
t.pass_count = w.exacts.length;
|
|
345
|
+
break;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
281
348
|
const win = { start_date: startStr.slice(0, 10), end_date: endStr.slice(0, 10) };
|
|
282
|
-
const summary = buildSummary(transits, aspectLabel, win);
|
|
349
|
+
const summary = buildSummary(transits, windows, aspectLabel, orbDeg, win);
|
|
283
350
|
const uiPayload = {
|
|
284
351
|
transits,
|
|
352
|
+
windows,
|
|
353
|
+
orb_deg: orbDeg,
|
|
285
354
|
natal_positions: natalPositionMap,
|
|
286
355
|
aspect_angle: aspectAngle,
|
|
287
356
|
aspect_label: aspectLabel,
|
|
@@ -6616,8 +6616,8 @@ function d_(e4, t2, n2, r2) {
|
|
|
6616
6616
|
var t4, n3, r3, i3, a3;
|
|
6617
6617
|
let o3 = ee2++;
|
|
6618
6618
|
te2[o3] = e6;
|
|
6619
|
-
let s3 = ((t4 = (n3 = e6.planet) == null ? e6.planet_name : n3) == null ? "" : t4).toLowerCase(), l3 = r_(s3), u3 = i_(s3), d3 = a_((r3 = e6.planet_name) == null ? s3 : r3), f3 = e6.is_retrograde ? '<span class="tl-retro" title="Retrograde at exact crossing">\u211E</span>' : "", p3 = (i3 = e6.aspect) == null ? c2 : i3, m3 = (a3 = n_[p3]) == null ? "" : a3, h3 = e6.natal_point ? '<span class="tl-natal">' + $(m3 ? m3 + " " : "") + $(p3) + ' natal <span class="tl-natal-glyph">' + $(i_(e6.natal_point)) + "</span> " + $(a_(e6.natal_point)) + "</span>" : '<span class="tl-natal">' + $(m3 ? m3 + " " : "") + $(a_(p3)) + "</span>", ne3 = u_(e6);
|
|
6620
|
-
return '<div class="tl-event" data-idx="' + o3 + '" tabindex="0" role="button" aria-label="' + $(d3 + " " + p3 + (e6.natal_point ? " natal " + e6.natal_point : "") + " on " + s_(e6.date)) + '"><div class="tl-event-rail" aria-hidden="true"><span class="tl-node" style="--planet-color:' + l3 + '"></span></div><div class="tl-event-glyph" style="--planet-color:' + l3 + '" aria-hidden="true">' + u3 + '</div><div class="tl-event-body"><div class="tl-event-line1"><span class="tl-planet-name">' + $(d3) + "</span>" + f3 + h3 + '</div><div class="tl-event-line2"><span class="tl-date">' + $(c_(e6.date)) + "</span>" + (ne3 ? '<span class="tl-dot">\xB7</span><span class="tl-pos">' + $(ne3) + "</span>" : "") + '</div
|
|
6619
|
+
let s3 = ((t4 = (n3 = e6.planet) == null ? e6.planet_name : n3) == null ? "" : t4).toLowerCase(), l3 = r_(s3), u3 = i_(s3), d3 = a_((r3 = e6.planet_name) == null ? s3 : r3), f3 = e6.is_retrograde ? '<span class="tl-retro" title="Retrograde at exact crossing">\u211E</span>' : "", p3 = (i3 = e6.aspect) == null ? c2 : i3, m3 = (a3 = n_[p3]) == null ? "" : a3, h3 = e6.natal_point ? '<span class="tl-natal">' + $(m3 ? m3 + " " : "") + $(p3) + ' natal <span class="tl-natal-glyph">' + $(i_(e6.natal_point)) + "</span> " + $(a_(e6.natal_point)) + "</span>" : '<span class="tl-natal">' + $(m3 ? m3 + " " : "") + $(a_(p3)) + "</span>", ne3 = u_(e6), re3 = e6.window_start === void 0 ? "" : "In orb " + (e6.window_start ? s_(e6.window_start) : "\u2026") + " \u2013 " + (e6.window_end ? s_(e6.window_end) : "\u2026") + (e6.pass_count && e6.pass_count > 1 ? " \xB7 pass " + e6.pass_index + " of " + e6.pass_count : "");
|
|
6620
|
+
return '<div class="tl-event" data-idx="' + o3 + '" tabindex="0" role="button" aria-label="' + $(d3 + " " + p3 + (e6.natal_point ? " natal " + e6.natal_point : "") + " on " + s_(e6.date)) + '"><div class="tl-event-rail" aria-hidden="true"><span class="tl-node" style="--planet-color:' + l3 + '"></span></div><div class="tl-event-glyph" style="--planet-color:' + l3 + '" aria-hidden="true">' + u3 + '</div><div class="tl-event-body"><div class="tl-event-line1"><span class="tl-planet-name">' + $(d3) + "</span>" + f3 + h3 + '</div><div class="tl-event-line2"><span class="tl-date">' + $(c_(e6.date)) + "</span>" + (ne3 ? '<span class="tl-dot">\xB7</span><span class="tl-pos">' + $(ne3) + "</span>" : "") + "</div>" + (re3 ? '<div class="tl-event-line2"><span class="tl-pos">' + $(re3) + "</span></div>" : "") + '<button class="tl-ask" type="button" data-ask="' + o3 + '">\u2728 Interpret this transit</button></div></div>';
|
|
6621
6621
|
}).join("");
|
|
6622
6622
|
return '<section class="tl-group"><h2 class="tl-group-label">' + $(e5.key) + '</h2><div class="tl-events">' + t3 + "</div></section>";
|
|
6623
6623
|
}).join(""), h2 = "";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openephemeris/mcp-server",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.17.0",
|
|
4
4
|
"description": "MCP server for Open Ephemeris — NASA JPL DE440 astrology and astronomy, with interactive charts that render inline in Claude and ChatGPT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|