@openephemeris/mcp-server 4.7.0 → 4.8.1

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.
Files changed (42) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/README.md +35 -3
  3. package/dist/index.js +5 -2
  4. package/dist/oauth/token.js +30 -3
  5. package/dist/server-sse.js +7 -2
  6. package/dist/tools/apps/bazi-app.js +4 -4
  7. package/dist/tools/apps/bi-wheel-app.js +57 -23
  8. package/dist/tools/apps/bodygraph-app.js +12 -9
  9. package/dist/tools/apps/chart-wheel-app.js +4 -4
  10. package/dist/tools/apps/location-tools.js +2 -2
  11. package/dist/tools/apps/moon-phase-app.js +1 -1
  12. package/dist/tools/apps/vedic-chart-app.js +1 -1
  13. package/dist/tools/auth.js +8 -0
  14. package/dist/tools/dev.js +15 -5
  15. package/dist/tools/index.d.ts +41 -2
  16. package/dist/tools/index.js +201 -4
  17. package/dist/tools/specialized/account.js +5 -1
  18. package/dist/tools/specialized/acg.js +2 -2
  19. package/dist/tools/specialized/bazi.js +7 -7
  20. package/dist/tools/specialized/bi_wheel.js +1 -1
  21. package/dist/tools/specialized/chart_wheel.js +1 -1
  22. package/dist/tools/specialized/comparative.js +4 -4
  23. package/dist/tools/specialized/eclipse.js +1 -1
  24. package/dist/tools/specialized/electional.js +5 -5
  25. package/dist/tools/specialized/ephemeris_core.js +2 -2
  26. package/dist/tools/specialized/ephemeris_extended.js +8 -8
  27. package/dist/tools/specialized/hd_bodygraph.js +1 -1
  28. package/dist/tools/specialized/hd_cycles.js +2 -2
  29. package/dist/tools/specialized/hd_group.js +2 -2
  30. package/dist/tools/specialized/human_design.js +1 -1
  31. package/dist/tools/specialized/moon.js +10 -13
  32. package/dist/tools/specialized/natal.js +1 -1
  33. package/dist/tools/specialized/progressed.js +1 -1
  34. package/dist/tools/specialized/relocation.js +1 -1
  35. package/dist/tools/specialized/returns.js +3 -3
  36. package/dist/tools/specialized/synastry.js +1 -1
  37. package/dist/tools/specialized/transits.js +1 -1
  38. package/dist/tools/specialized/vedic.js +1 -1
  39. package/dist/tools/specialized/venus_star_points.js +6 -6
  40. package/dist/ui/chart-wheel.html +56 -53
  41. package/package.json +4 -2
  42. package/smithery.yaml +14 -3
@@ -53,7 +53,7 @@ registerTool({
53
53
  additionalProperties: false,
54
54
  },
55
55
  outputSchema: OUTPUT_SCHEMA_JSON,
56
- annotations: { title: "HD Composite Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
56
+ annotations: { title: "HD Composite Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
57
57
  handler: async (args) => {
58
58
  validateRequired(args, ["person_a_datetime", "person_b_datetime"]);
59
59
  const body = {
@@ -123,7 +123,7 @@ registerTool({
123
123
  additionalProperties: false,
124
124
  },
125
125
  outputSchema: OUTPUT_SCHEMA_JSON,
126
- annotations: { title: "HD Penta Group Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
126
+ annotations: { title: "HD Penta Group Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
127
127
  handler: async (args) => {
128
128
  validateRequired(args, ["group_name", "members"]);
129
129
  const members = await Promise.all(args.members.map(async (m, i) => ({
@@ -62,7 +62,7 @@ registerTool({
62
62
  additionalProperties: false,
63
63
  },
64
64
  outputSchema: OUTPUT_SCHEMA_IMAGE_AND_JSON,
65
- annotations: { title: "Human Design Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
65
+ annotations: { title: "Human Design Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
66
66
  handler: async (args) => {
67
67
  validateRequired(args, ["datetime"]);
68
68
  const body = {
@@ -6,20 +6,16 @@ import { localToUtcIsoHistorical } from "../datetime-historical.js";
6
6
  registerTool({
7
7
  name: "ephemeris_moon_phase",
8
8
  description: "Get the Moon's current phase angle, illumination, sign and void-of-course status AT a " +
9
- "specific point in time. Returns phase name (New, Waxing Crescent, First Quarter, etc.), exact " +
10
- "angle, illumination %, the zodiac sign and degree the Moon occupies, and next void-of-course " +
11
- "period.\n\n" +
9
+ "specific point in time. Returns phase name (New, Waxing Crescent, etc.), illumination %, " +
10
+ "the zodiac sign and degree the Moon occupies, and next void-of-course period.\n\n" +
12
11
  "⚠️ THIS TOOL ANSWERS: 'What phase is the moon in right now (or at a given datetime)?' and " +
13
12
  "'What sign is the moon in?'\n" +
14
13
  "❌ THIS TOOL DOES NOT ANSWER: 'When is the next new moon / full moon?'\n" +
15
14
  "→ For upcoming phase DATES use ephemeris_next_lunar_phase instead.\n\n" +
16
15
  "For a user-facing interactive moon-phase dial, use explore_moon_phase instead.\n\n" +
17
- "CREDIT COST: 1 credit per call.\n\n" +
18
- "If no datetime is provided, returns the current (live) moon phase.\n\n" +
19
- "EXAMPLE: Get moon phase for a specific date/time:\n" +
20
- " datetime='2026-03-20T12:00:00Z'\n\n" +
21
- "EXAMPLE: Get the current moon phase right now:\n" +
22
- " (call with no arguments)",
16
+ "CREDIT COST: 2 credits — phase and void-of-course are metered separately. For " +
17
+ "phase alone at 1 credit, use dev_read_api path='/ephemeris/moon/phase'.\n\n" +
18
+ "If no datetime is provided, returns the current (live) moon phase.",
23
19
  inputSchema: {
24
20
  type: "object",
25
21
  properties: {
@@ -43,7 +39,7 @@ registerTool({
43
39
  additionalProperties: false,
44
40
  },
45
41
  outputSchema: OUTPUT_SCHEMA_JSON,
46
- annotations: { title: "Moon Phase", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
42
+ annotations: { title: "Moon Phase", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
47
43
  handler: async (args) => {
48
44
  validateCoordinates(args, "latitude", "longitude");
49
45
  const params = {};
@@ -74,8 +70,9 @@ registerTool({
74
70
  "'What date is the next quarter moon?', or any question about UPCOMING phase dates.\n" +
75
71
  "❌ NOT FOR: 'What phase is the moon in right now?' or 'What sign is the moon in?'\n" +
76
72
  "→ For the phase, sign and degree AT a moment, use ephemeris_moon_phase.\n\n" +
77
- "CREDIT COST: about 1 credit per occurrence returned — count=1 costs 1 credit, " +
78
- "count=3 costs 3.\n\n" +
73
+ "CREDIT COST: 1-2 credits per occurrence returned — each occurrence takes one " +
74
+ "calendar search, plus a second search when the first window misses. So count=3 " +
75
+ "costs 3-6 credits.\n\n" +
79
76
  "EXAMPLE: Find the next new moon:\n" +
80
77
  " phase='new_moon'\n\n" +
81
78
  "EXAMPLE: Find the next full moon after a specific date:\n" +
@@ -107,7 +104,7 @@ registerTool({
107
104
  additionalProperties: false,
108
105
  },
109
106
  outputSchema: OUTPUT_SCHEMA_JSON,
110
- annotations: { title: "Next Lunar Phase", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
107
+ annotations: { title: "Next Lunar Phase", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
111
108
  handler: async (args) => {
112
109
  const PHASE_LABELS = {
113
110
  new_moon: "New Moon",
@@ -73,7 +73,7 @@ registerTool({
73
73
  additionalProperties: false,
74
74
  },
75
75
  outputSchema: OUTPUT_SCHEMA_IMAGE_AND_JSON,
76
- annotations: { title: "Natal Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
76
+ annotations: { title: "Natal Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
77
77
  handler: async (args) => {
78
78
  validateRequired(args, ["datetime", "latitude", "longitude"]);
79
79
  assertZonedDatetime("datetime", args.datetime, args.timezone);
@@ -60,7 +60,7 @@ registerTool({
60
60
  additionalProperties: false,
61
61
  },
62
62
  outputSchema: OUTPUT_SCHEMA_IMAGE_AND_JSON,
63
- annotations: { title: "Progressed Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
63
+ annotations: { title: "Progressed Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
64
64
  handler: async (args) => {
65
65
  validateRequired(args, ["birth_datetime", "birth_latitude", "birth_longitude", "target_datetime"]);
66
66
  assertZonedDatetime("birth_datetime", args.birth_datetime, args.timezone);
@@ -51,7 +51,7 @@ registerTool({
51
51
  additionalProperties: false,
52
52
  },
53
53
  outputSchema: OUTPUT_SCHEMA_JSON,
54
- annotations: { title: "Relocation Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
54
+ annotations: { title: "Relocation Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
55
55
  handler: async (args) => {
56
56
  validateRequired(args, ["natal_datetime", "natal_latitude", "natal_longitude", "relocation_latitude", "relocation_longitude"]);
57
57
  assertZonedDatetime("natal_datetime", args.natal_datetime, args.timezone);
@@ -63,7 +63,7 @@ registerTool({
63
63
  additionalProperties: false,
64
64
  },
65
65
  outputSchema: OUTPUT_SCHEMA_IMAGE_AND_JSON,
66
- annotations: { title: "Solar Return", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
66
+ annotations: { title: "Solar Return", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
67
67
  handler: async (args) => {
68
68
  validateRequired(args, ["birth_datetime"]);
69
69
  assertZonedDatetime("birth_datetime", args.birth_datetime, args.timezone);
@@ -136,7 +136,7 @@ registerTool({
136
136
  },
137
137
  // JSON only: this tool never sets include_visual, so it cannot return an image.
138
138
  outputSchema: OUTPUT_SCHEMA_JSON,
139
- annotations: { title: "Lunar Return", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
139
+ annotations: { title: "Lunar Return", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
140
140
  handler: async (args) => {
141
141
  validateRequired(args, ["birth_datetime"]);
142
142
  assertZonedDatetime("birth_datetime", args.birth_datetime, args.timezone);
@@ -196,7 +196,7 @@ registerTool({
196
196
  },
197
197
  // JSON only: this tool never sets include_visual, so it cannot return an image.
198
198
  outputSchema: OUTPUT_SCHEMA_JSON,
199
- annotations: { title: "Planetary Return", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
199
+ annotations: { title: "Planetary Return", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
200
200
  handler: async (args) => {
201
201
  validateRequired(args, ["body", "birth_datetime", "target_datetime"]);
202
202
  assertZonedDatetime("birth_datetime", args.birth_datetime, args.timezone);
@@ -57,7 +57,7 @@ registerTool({
57
57
  additionalProperties: false,
58
58
  },
59
59
  outputSchema: OUTPUT_SCHEMA_IMAGE_AND_JSON,
60
- annotations: { title: "Synastry Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
60
+ annotations: { title: "Synastry Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
61
61
  handler: async (args) => {
62
62
  validateRequired(args, [
63
63
  "person_a_datetime", "person_a_latitude", "person_a_longitude",
@@ -64,7 +64,7 @@ registerTool({
64
64
  additionalProperties: false,
65
65
  },
66
66
  outputSchema: OUTPUT_SCHEMA_JSON,
67
- annotations: { title: "Transit Search", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
67
+ annotations: { title: "Transit Search", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
68
68
  handler: async (args) => {
69
69
  validateRequired(args, ["natal_datetime", "natal_latitude", "natal_longitude", "start_date", "end_date"]);
70
70
  // ── Step 1: Compute natal chart to extract real planetary longitudes ──
@@ -38,7 +38,7 @@ registerTool({
38
38
  additionalProperties: false,
39
39
  },
40
40
  outputSchema: OUTPUT_SCHEMA_JSON,
41
- annotations: { title: "Vedic Natal Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
41
+ annotations: { title: "Vedic Natal Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
42
42
  handler: async (args) => {
43
43
  validateRequired(args, ["datetime", "latitude", "longitude"]);
44
44
  validateCoordinates(args, "latitude", "longitude");
@@ -35,7 +35,7 @@ registerTool({
35
35
  additionalProperties: false,
36
36
  },
37
37
  outputSchema: OUTPUT_SCHEMA_JSON,
38
- annotations: { title: "Venus Star Points", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
38
+ annotations: { title: "Venus Star Points", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
39
39
  handler: async (args) => {
40
40
  validateRequired(args, ["datetime", "latitude", "longitude"]);
41
41
  assertZonedDatetime("datetime", args.datetime, args.timezone);
@@ -67,7 +67,7 @@ registerTool({
67
67
  additionalProperties: false,
68
68
  },
69
69
  outputSchema: OUTPUT_SCHEMA_JSON,
70
- annotations: { title: "Venus Conjunctions", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
70
+ annotations: { title: "Venus Conjunctions", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
71
71
  handler: async (args) => {
72
72
  validateRequired(args, ["start_date", "end_date"]);
73
73
  const query = {};
@@ -98,7 +98,7 @@ registerTool({
98
98
  additionalProperties: false,
99
99
  },
100
100
  outputSchema: OUTPUT_SCHEMA_JSON,
101
- annotations: { title: "Venus 8-Year Star", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
101
+ annotations: { title: "Venus 8-Year Star", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
102
102
  handler: async (args) => {
103
103
  validateRequired(args, ["date"]);
104
104
  const query = {};
@@ -130,7 +130,7 @@ registerTool({
130
130
  additionalProperties: false,
131
131
  },
132
132
  outputSchema: OUTPUT_SCHEMA_JSON,
133
- annotations: { title: "Venus Phase", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
133
+ annotations: { title: "Venus Phase", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
134
134
  handler: async (args) => {
135
135
  const query = {};
136
136
  if (args.format)
@@ -158,7 +158,7 @@ registerTool({
158
158
  additionalProperties: false,
159
159
  },
160
160
  outputSchema: OUTPUT_SCHEMA_JSON,
161
- annotations: { title: "Venus Elongations", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
161
+ annotations: { title: "Venus Elongations", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
162
162
  handler: async (args) => {
163
163
  validateRequired(args, ["start_date", "end_date"]);
164
164
  const query = {};
@@ -189,7 +189,7 @@ registerTool({
189
189
  additionalProperties: false,
190
190
  },
191
191
  outputSchema: OUTPUT_SCHEMA_JSON,
192
- annotations: { title: "Venus Stations", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
192
+ annotations: { title: "Venus Stations", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
193
193
  handler: async (args) => {
194
194
  validateRequired(args, ["start_date"]);
195
195
  const query = {};
@@ -7690,8 +7690,8 @@ function Cy(e5) {
7690
7690
  vy.ontoolresult = (e5) => {
7691
7691
  var t2;
7692
7692
  let n2 = ny(e5);
7693
- if (qy(), !n2 || !n2.planets) {
7694
- console.error("[ChartWheel] \u274C No chart data found in tool result"), Jy("Chart data could not be parsed from the server response.", Yy);
7693
+ if (Jy(), !n2 || !n2.planets) {
7694
+ console.error("[ChartWheel] \u274C No chart data found in tool result"), Yy("Chart data could not be parsed from the server response.", Xy);
7695
7695
  return;
7696
7696
  }
7697
7697
  if ($ = n2, yy = (t2 = n2.house_system) == null ? "placidus" : t2, !by) {
@@ -7718,9 +7718,9 @@ vy.ontoolresult = (e5) => {
7718
7718
  };
7719
7719
  function wy(e5) {
7720
7720
  var t2, n2, r2, i2, a2, o2, s2;
7721
- ky = null, ly.setAttribute("hidden", ""), uy.removeAttribute("hidden"), _y.removeAttribute("hidden"), py.removeAttribute("hidden"), zv(uy, e5, Ly, Ry, zy, Wy, Sy ? By() : void 0), mv(Cy), Hv(py, yy, Gy), Ty(e5), ty("chart-wheel", uy);
7721
+ Ay = null, ly.setAttribute("hidden", ""), uy.removeAttribute("hidden"), _y.removeAttribute("hidden"), py.removeAttribute("hidden"), zv(uy, e5, Ry, zy, By, Gy, Sy ? Vy() : void 0), mv(Cy), Hv(py, yy, Ky), Ey(e5), ty("chart-wheel", uy);
7722
7722
  let c2 = K_(e5.planets), l2 = (n2 = (r2 = (i2 = ((t2 = e5.houses) == null ? [] : t2)[0]) == null ? void 0 : i2.cusp_lon) == null ? e5.ascendant : r2) == null ? 0 : n2, u2 = (a2 = e5.aspects) == null ? [] : a2;
7723
- c2.length > 0 && Dy(c2, u2), Ay(cv(u2, c2), c2, l2), Fy();
7723
+ c2.length > 0 && Oy(c2, u2), jy(cv(u2, c2), c2, l2), Iy();
7724
7724
  let d2 = document.getElementById("cw-action-bar");
7725
7725
  if (!d2) {
7726
7726
  d2 = document.createElement("div"), d2.id = "cw-action-bar", d2.className = "hd-action-bar";
@@ -7731,9 +7731,12 @@ function wy(e5) {
7731
7731
  (f2 = document.getElementById("app")) == null || f2.prepend(d2);
7732
7732
  }
7733
7733
  }
7734
- d2.innerHTML = '\n <button class="action-btn action-btn--primary" id="cw-interpret-btn">\u2728 Interpret this chart</button>\n <button class="action-btn" id="cw-questions-btn">\u{1F52E} What should I ask?</button>\n ', (o2 = document.getElementById("cw-interpret-btn")) == null || o2.addEventListener("click", () => void Hy()), (s2 = document.getElementById("cw-questions-btn")) == null || s2.addEventListener("click", () => void Uy());
7734
+ d2.innerHTML = '\n <button class="action-btn action-btn--primary" id="cw-interpret-btn">\u2728 Interpret this chart</button>\n <button class="action-btn" id="cw-questions-btn">\u{1F52E} What should I ask?</button>\n ', (o2 = document.getElementById("cw-interpret-btn")) == null || o2.addEventListener("click", () => void Uy()), (s2 = document.getElementById("cw-questions-btn")) == null || s2.addEventListener("click", () => void Wy());
7735
7735
  }
7736
7736
  function Ty(e5) {
7737
+ return String(e5).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
7738
+ }
7739
+ function Ey(e5) {
7737
7740
  var t2, n2, r2, i2, a2, o2, s2, c2, l2, u2;
7738
7741
  if (!dy) return;
7739
7742
  let d2 = (t2 = e5._birth_params) == null ? {} : t2, f2 = (n2 = (r2 = (i2 = d2.datetime) == null ? e5.datetime : i2) == null ? e5.birth_datetime : r2) == null ? "" : n2, p2 = (a2 = (o2 = d2.location) == null ? e5.location : o2) == null ? "" : a2, m2 = (s2 = (c2 = d2.timezone) == null ? e5.timezone : c2) == null ? "" : s2, h2 = (l2 = d2.latitude) == null ? e5.latitude : l2, g2 = (u2 = d2.longitude) == null ? e5.longitude : u2;
@@ -7747,14 +7750,14 @@ function Ty(e5) {
7747
7750
  } catch (e6) {
7748
7751
  }
7749
7752
  let y2 = typeof h2 == "number" && typeof g2 == "number" ? "".concat(Math.abs(h2).toFixed(2), "\xB0").concat(h2 >= 0 ? "N" : "S", ", ").concat(Math.abs(g2).toFixed(2), "\xB0").concat(g2 >= 0 ? "E" : "W") : "", b2 = [];
7750
- if (ee2 && b2.push('<span class="info-chip" title="Birth datetime">\u{1F4C5} '.concat(ee2, "</span>")), p2 && b2.push('<span class="info-chip" title="Birth location">\u{1F4CD} '.concat(p2, "</span>")), y2 && !p2 && b2.push('<span class="info-chip" title="Coordinates">\u{1F4CD} '.concat(y2, "</span>")), m2 && b2.push('<span class="info-chip" title="Timezone">\u{1F550} '.concat(m2, "</span>")), v2 && b2.push('<span class="info-chip sect" title="Sect">'.concat(v2, "</span>")), b2.length === 0) {
7753
+ if (ee2 && b2.push('<span class="info-chip" title="Birth datetime">\u{1F4C5} '.concat(Ty(ee2), "</span>")), p2 && b2.push('<span class="info-chip" title="Birth location">\u{1F4CD} '.concat(Ty(p2), "</span>")), y2 && !p2 && b2.push('<span class="info-chip" title="Coordinates">\u{1F4CD} '.concat(Ty(y2), "</span>")), m2 && b2.push('<span class="info-chip" title="Timezone">\u{1F550} '.concat(Ty(m2), "</span>")), v2 && b2.push('<span class="info-chip sect" title="Sect">'.concat(Ty(v2), "</span>")), b2.length === 0) {
7751
7754
  dy.setAttribute("hidden", "");
7752
7755
  return;
7753
7756
  }
7754
7757
  dy.innerHTML = b2.join(""), dy.removeAttribute("hidden");
7755
7758
  }
7756
- var Ey = /* @__PURE__ */ new Set(["mean_lilith", "lilith", "true_lilith", "ceres", "juno", "vesta", "pallas", "pholus", "vertex", "part_of_fortune", "part of fortune", "eris", "sedna"]);
7757
- function Dy(e5, t2) {
7759
+ var Dy = /* @__PURE__ */ new Set(["mean_lilith", "lilith", "true_lilith", "ceres", "juno", "vesta", "pallas", "pholus", "vertex", "part_of_fortune", "part of fortune", "eris", "sedna"]);
7760
+ function Oy(e5, t2) {
7758
7761
  if (!gy || e5.length === 0) return;
7759
7762
  let n2 = ["sun", "moon", "mercury", "venus", "mars", "jupiter", "saturn", "uranus", "neptune", "pluto", "chiron", "north node", "south node", "true node"], r2 = [...e5].sort((e6, t3) => {
7760
7763
  let r3 = n2.indexOf(e6.name.toLowerCase()), i3 = n2.indexOf(t3.name.toLowerCase());
@@ -7766,7 +7769,7 @@ function Dy(e5, t2) {
7766
7769
  }
7767
7770
  let s2 = (e6) => e6.replace(/(^|\s|_)\w/g, (e7) => e7.toUpperCase()).replace(/_/g, " "), c2 = (e6) => ["Aries", "Taurus", "Gemini", "Cancer", "Leo", "Virgo", "Libra", "Scorpio", "Sagittarius", "Capricorn", "Aquarius", "Pisces"][Math.floor((e6 % 360 + 360) % 360 / 30)], l2 = r2.map((e6) => {
7768
7771
  var t3, n3, r3, a3;
7769
- let o3 = e6.name.toLowerCase(), l3 = (t3 = j_[o3]) == null ? "\u2605" : t3, u3 = (n3 = e6.sign) == null ? c2(e6.longitude) : n3, d3 = Math.floor((e6.longitude % 360 + 360) % 360 % 30), f3 = Math.floor((e6.longitude % 360 + 360) % 360 % 1 * 60), p3 = Ey.has(o3), m2 = e6.retrograde ? '<span class="retro-mark">\u211E</span>' : "", h2 = (r3 = i2[o3]) == null ? 0 : r3;
7772
+ let o3 = e6.name.toLowerCase(), l3 = (t3 = j_[o3]) == null ? "\u2605" : t3, u3 = (n3 = e6.sign) == null ? c2(e6.longitude) : n3, d3 = Math.floor((e6.longitude % 360 + 360) % 360 % 30), f3 = Math.floor((e6.longitude % 360 + 360) % 360 % 1 * 60), p3 = Dy.has(o3), m2 = e6.retrograde ? '<span class="retro-mark">\u211E</span>' : "", h2 = (r3 = i2[o3]) == null ? 0 : r3;
7770
7773
  return '<tr class="'.concat(p3 ? "extended-row" : "", '" data-planet="').concat(o3, '">\n <td><span class="planet-sym">').concat(l3, "</span> ").concat(s2(e6.name)).concat(m2, "</td>\n <td>").concat(d3, "\xB0 ").concat(u3, " ").concat(String(f3).padStart(2, "0"), "\u2032</td>\n <td>H").concat((a3 = e6.house) == null ? "\u2013" : a3, "</td>\n <td>").concat(h2 > 0 ? h2 : "\u2013", "</td>\n </tr>");
7771
7774
  }).join(""), u2 = "| Body | Sign | Degree | House | Retrograde |\n| --- | --- | --- | --- | --- |\n" + r2.map((e6) => {
7772
7775
  var t3;
@@ -7784,7 +7787,7 @@ function Dy(e5, t2) {
7784
7787
  d2.textContent = "Copy", d2.classList.remove("copied");
7785
7788
  }, 1600);
7786
7789
  } catch (e7) {
7787
- Oy("Copy unavailable");
7790
+ ky("Copy unavailable");
7788
7791
  }
7789
7792
  });
7790
7793
  let f2 = gy.querySelector(".overview-toggle"), p2 = gy.querySelector(".overview-body");
@@ -7803,7 +7806,7 @@ function Dy(e5, t2) {
7803
7806
  let t4 = document.querySelector("svg");
7804
7807
  t4 && (t4.querySelectorAll(".planet-glyph-group").forEach((e7) => {
7805
7808
  var t5;
7806
- let n4 = Ey.has((t5 = e7.dataset.planet) == null ? "" : t5);
7809
+ let n4 = Dy.has((t5 = e7.dataset.planet) == null ? "" : t5);
7807
7810
  e7.style.opacity = n4 ? "0.65" : "1";
7808
7811
  }), e6.classList.remove("active-row"));
7809
7812
  }), e6.addEventListener("click", () => {
@@ -7814,7 +7817,7 @@ function Dy(e5, t2) {
7814
7817
  }));
7815
7818
  });
7816
7819
  }
7817
- function Oy(e5) {
7820
+ function ky(e5) {
7818
7821
  var t2;
7819
7822
  (t2 = document.getElementById("copy-toast")) == null || t2.remove();
7820
7823
  let n2 = document.createElement("div");
@@ -7822,8 +7825,8 @@ function Oy(e5) {
7822
7825
  n2.classList.remove("visible"), setTimeout(() => n2.remove(), 300);
7823
7826
  }, 2500);
7824
7827
  }
7825
- var ky = null;
7826
- function Ay(e5, t2, n2) {
7828
+ var Ay = null;
7829
+ function jy(e5, t2, n2) {
7827
7830
  if (!my) return;
7828
7831
  if (e5.length === 0) {
7829
7832
  my.setAttribute("hidden", ""), my.innerHTML = "";
@@ -7838,10 +7841,10 @@ function Ay(e5, t2, n2) {
7838
7841
  let t3 = document.createElement("button");
7839
7842
  t3.className = "pattern-ask-claude-btn", t3.textContent = "\u2728 Ask Claude", t3.style.display = "none", my.appendChild(t3), t3.addEventListener("click", () => {
7840
7843
  var n3;
7841
- let r3 = ky;
7844
+ let r3 = Ay;
7842
7845
  if (r3 === null) return;
7843
7846
  let i2 = e5[r3];
7844
- t3.disabled = true, t3.textContent = "\u23F3 Sending\u2026", Wy({ type: "pattern", data: { name: i2.name, planets: i2.planets, description: (n3 = i2.description) == null ? "" : n3 } }).then(() => {
7847
+ t3.disabled = true, t3.textContent = "\u23F3 Sending\u2026", Gy({ type: "pattern", data: { name: i2.name, planets: i2.planets, description: (n3 = i2.description) == null ? "" : n3 } }).then(() => {
7845
7848
  t3.textContent = "\u2713 Sent", setTimeout(() => {
7846
7849
  t3.textContent = "\u2728 Ask Claude", t3.disabled = false;
7847
7850
  }, 2500);
@@ -7854,12 +7857,12 @@ function Ay(e5, t2, n2) {
7854
7857
  r3.addEventListener("click", () => {
7855
7858
  var i2;
7856
7859
  let a2 = Number(r3.dataset.idx), o2 = e5[a2], s2 = (i2 = r3.dataset.color) == null ? "#888" : i2, c2 = my.querySelector(".pattern-ask-claude-btn");
7857
- ky === a2 ? (ky = null, Mv(), c2 && (c2.style.display = "none"), my.querySelectorAll(".pattern-pill").forEach((e6) => {
7860
+ Ay === a2 ? (Ay = null, Mv(), c2 && (c2.style.display = "none"), my.querySelectorAll(".pattern-pill").forEach((e6) => {
7858
7861
  var t3;
7859
7862
  e6.classList.remove("active");
7860
7863
  let n3 = (t3 = e6.dataset.color) == null ? "#888" : t3;
7861
7864
  e6.style.color = n3, e6.style.borderColor = n3, e6.style.background = "transparent";
7862
- })) : (ky = a2, my.querySelectorAll(".pattern-pill").forEach((e6) => {
7865
+ })) : (Ay = a2, my.querySelectorAll(".pattern-pill").forEach((e6) => {
7863
7866
  var t3;
7864
7867
  e6.classList.remove("active");
7865
7868
  let n3 = (t3 = e6.dataset.color) == null ? "#888" : t3;
@@ -7868,8 +7871,8 @@ function Ay(e5, t2, n2) {
7868
7871
  });
7869
7872
  });
7870
7873
  }
7871
- var jy = [{ label: "Tight", maxOrb: 4 }, { label: "Standard", maxOrb: 8 }, { label: "Wide", maxOrb: 12 }], My = true, Ny = 8, Py = "true";
7872
- function Fy() {
7874
+ var My = [{ label: "Tight", maxOrb: 4 }, { label: "Standard", maxOrb: 8 }, { label: "Wide", maxOrb: 12 }], Ny = true, Py = 8, Fy = "true";
7875
+ function Iy() {
7873
7876
  var e5;
7874
7877
  if (!hy) return;
7875
7878
  let t2 = (() => {
@@ -7881,9 +7884,9 @@ function Fy() {
7881
7884
  let n3 = t3.some((e7) => e7 === "north node" || e7 === "north node (mean)" || e7 === "mean node"), r3 = t3.some((e7) => e7 === "true node" || e7 === "north node (true)");
7882
7885
  return n3 && r3;
7883
7886
  })();
7884
- W_(Py);
7885
- let n2 = t2 ? '\n <div class="asp-section">\n <span class="asp-section-label">Nodes</span>\n <button class="orb-preset-btn node-btn'.concat(Py === "mean" ? " active" : "", '" data-node="mean" title="Mean lunar node (averaged orbit)">Mean</button>\n <button class="orb-preset-btn node-btn').concat(Py === "true" ? " active" : "", '" data-node="true" title="True (osculating) lunar node">True</button>\n </div>') : "";
7886
- My = true, hy.innerHTML = '\n <div class="asp-panel">\n <div class="asp-section">\n <span class="asp-section-label">Aspects</span>\n <button class="aspect-toggle-btn active" id="cw-aspect-vis-toggle"\n title="Toggle all natal aspect lines">\n <span class="toggle-icon">\u2295</span> Natal aspects\n </button>\n </div>\n <div class="asp-section">\n <span class="asp-section-label">Orb</span>\n '.concat(jy.map((e6) => '<button class="orb-preset-btn'.concat(e6.maxOrb === Ny ? " active" : "", '" data-orb="').concat(e6.maxOrb, '" title="').concat(e6.label, ' orbs">').concat(e6.label, "</button>")).join(""), "\n </div>").concat(n2, "\n </div>\n ");
7887
+ W_(Fy);
7888
+ let n2 = t2 ? '\n <div class="asp-section">\n <span class="asp-section-label">Nodes</span>\n <button class="orb-preset-btn node-btn'.concat(Fy === "mean" ? " active" : "", '" data-node="mean" title="Mean lunar node (averaged orbit)">Mean</button>\n <button class="orb-preset-btn node-btn').concat(Fy === "true" ? " active" : "", '" data-node="true" title="True (osculating) lunar node">True</button>\n </div>') : "";
7889
+ Ny = true, hy.innerHTML = '\n <div class="asp-panel">\n <div class="asp-section">\n <span class="asp-section-label">Aspects</span>\n <button class="aspect-toggle-btn active" id="cw-aspect-vis-toggle"\n title="Toggle all natal aspect lines">\n <span class="toggle-icon">\u2295</span> Natal aspects\n </button>\n </div>\n <div class="asp-section">\n <span class="asp-section-label">Orb</span>\n '.concat(My.map((e6) => '<button class="orb-preset-btn'.concat(e6.maxOrb === Py ? " active" : "", '" data-orb="').concat(e6.maxOrb, '" title="').concat(e6.label, ' orbs">').concat(e6.label, "</button>")).join(""), "\n </div>").concat(n2, "\n </div>\n ");
7887
7890
  let r2 = K_($ == null ? void 0 : $.planets), i2 = /* @__PURE__ */ new Set(), a2 = [];
7888
7891
  for (let e6 of r2) {
7889
7892
  let t3 = e6.name.toLowerCase();
@@ -7902,21 +7905,21 @@ function Fy() {
7902
7905
  hy.insertAdjacentHTML("beforeend", Kv([{ title: "Bodies", items: a2 }, { title: "Aspects", items: o2 }])), hy.removeAttribute("hidden");
7903
7906
  let s2 = document.getElementById("cw-aspect-vis-toggle");
7904
7907
  s2 == null || s2.addEventListener("click", () => {
7905
- My = !My, Lv(My), s2.classList.toggle("active", My), s2.querySelector(".toggle-icon").textContent = My ? "\u2295" : "\u2296";
7908
+ Ny = !Ny, Lv(Ny), s2.classList.toggle("active", Ny), s2.querySelector(".toggle-icon").textContent = Ny ? "\u2295" : "\u2296";
7906
7909
  }), hy.querySelectorAll(".orb-preset-btn:not(.node-btn)").forEach((e6) => {
7907
7910
  e6.addEventListener("click", () => {
7908
7911
  var t3;
7909
7912
  let n3 = parseFloat((t3 = e6.dataset.orb) == null ? "8" : t3);
7910
- n3 !== Ny && (Ny = n3, hy.querySelectorAll(".orb-preset-btn:not(.node-btn)").forEach((e7) => e7.classList.toggle("active", e7.dataset.orb === String(n3))), Rv(n3));
7913
+ n3 !== Py && (Py = n3, hy.querySelectorAll(".orb-preset-btn:not(.node-btn)").forEach((e7) => e7.classList.toggle("active", e7.dataset.orb === String(n3))), Rv(n3));
7911
7914
  });
7912
7915
  }), hy.querySelectorAll(".node-btn").forEach((e6) => {
7913
7916
  e6.addEventListener("click", () => {
7914
7917
  let t3 = e6.dataset.node === "mean" ? "mean" : "true";
7915
- t3 === Py || !$ || (Py = t3, W_(t3), wy($));
7918
+ t3 === Fy || !$ || (Fy = t3, W_(t3), wy($));
7916
7919
  });
7917
7920
  });
7918
7921
  }
7919
- async function Iy(e5, t2) {
7922
+ async function Ly(e5, t2) {
7920
7923
  if (xy) try {
7921
7924
  let n2 = "[Chart Wheel] Selected ".concat(e5, " \u2014 ").concat(Object.entries(t2).filter(([, e6]) => e6 != null && e6 !== false && e6 !== "").map(([e6, t3]) => "".concat(e6, ": ").concat(t3)).join(", "));
7922
7925
  await vy.updateModelContext({ content: [{ type: "text", text: n2 }] });
@@ -7924,24 +7927,24 @@ async function Iy(e5, t2) {
7924
7927
  console.warn("[ChartWheel] \u26A0\uFE0F updateModelContext failed:", e6);
7925
7928
  }
7926
7929
  }
7927
- async function Ly(e5) {
7930
+ async function Ry(e5) {
7928
7931
  var t2, n2, r2, i2;
7929
- ky = null, my == null || my.querySelectorAll(".pattern-pill").forEach((e6) => {
7932
+ Ay = null, my == null || my.querySelectorAll(".pattern-pill").forEach((e6) => {
7930
7933
  var t3;
7931
7934
  e6.classList.remove("active");
7932
7935
  let n3 = (t3 = e6.dataset.color) == null ? "#888" : t3;
7933
7936
  e6.style.color = n3, e6.style.borderColor = n3, e6.style.background = "transparent";
7934
- }), await Iy("planet", { planet: e5.name, longitude: e5.longitude, sign: (t2 = e5.sign) == null ? null : t2, house: (n2 = e5.house) == null ? null : n2, retrograde: (r2 = e5.retrograde) == null ? false : r2, speed: (i2 = e5.speed) == null ? null : i2 });
7937
+ }), await Ly("planet", { planet: e5.name, longitude: e5.longitude, sign: (t2 = e5.sign) == null ? null : t2, house: (n2 = e5.house) == null ? null : n2, retrograde: (r2 = e5.retrograde) == null ? false : r2, speed: (i2 = e5.speed) == null ? null : i2 });
7935
7938
  }
7936
- async function Ry(e5) {
7939
+ async function zy(e5) {
7937
7940
  var t2, n2;
7938
- await Iy("house", { house_number: e5.number, sign: (t2 = e5.sign) == null ? null : t2, cusp_longitude: e5.cusp_lon, ruler: (n2 = e5.ruler) == null ? null : n2 });
7941
+ await Ly("house", { house_number: e5.number, sign: (t2 = e5.sign) == null ? null : t2, cusp_longitude: e5.cusp_lon, ruler: (n2 = e5.ruler) == null ? null : n2 });
7939
7942
  }
7940
- async function zy(e5) {
7943
+ async function By(e5) {
7941
7944
  var t2, n2, r2, i2;
7942
- await Iy("aspect", { planet1: e5.planet1, planet2: e5.planet2, aspect_type: (t2 = e5.type) == null ? null : t2, orb: (n2 = e5.orb) == null ? null : n2, applying: (r2 = e5.applying) == null ? null : r2, angle: (i2 = e5.angle) == null ? null : i2 });
7945
+ await Ly("aspect", { planet1: e5.planet1, planet2: e5.planet2, aspect_type: (t2 = e5.type) == null ? null : t2, orb: (n2 = e5.orb) == null ? null : n2, applying: (r2 = e5.applying) == null ? null : r2, angle: (i2 = e5.angle) == null ? null : i2 });
7943
7946
  }
7944
- function By() {
7947
+ function Vy() {
7945
7948
  return async (e5) => {
7946
7949
  try {
7947
7950
  var t2, n2;
@@ -7952,30 +7955,30 @@ function By() {
7952
7955
  }
7953
7956
  };
7954
7957
  }
7955
- async function Vy(e5) {
7958
+ async function Hy(e5) {
7956
7959
  try {
7957
7960
  (await vy.sendMessage({ role: "user", content: [{ type: "text", text: e5 }] })).isError && console.error("[ChartWheel] Host rejected sendMessage");
7958
7961
  } catch (e6) {
7959
7962
  console.error("[ChartWheel] sendMessage failed:", e6);
7960
7963
  }
7961
7964
  }
7962
- async function Hy() {
7965
+ async function Uy() {
7963
7966
  var e5, t2, n2, r2;
7964
7967
  if (!$) return;
7965
7968
  let i2 = $, a2 = (e5 = i2._birth_params) == null ? {} : e5, o2 = (t2 = (n2 = a2.name) == null ? a2.location : n2) == null ? "this person" : t2, s2 = K_(i2.planets), c2 = ((r2 = i2.aspects) == null ? [] : r2).filter((e6) => {
7966
7969
  var t3;
7967
7970
  return ["conjunction", "opposition", "trine", "square", "sextile"].includes((t3 = e6.type) == null ? "" : t3);
7968
7971
  }).slice(0, 8).map((e6) => " \u2022 ".concat(e6.planet1, " ").concat(e6.type, " ").concat(e6.planet2, " (").concat(Number(e6.orb).toFixed(1), "\xB0, ").concat(e6.applying ? "applying" : "separating", ")")).join("\n") || " \u2022 No major aspects found";
7969
- await Vy("Please give a complete natal chart interpretation for ".concat(o2, ".\n\nKey planet placements:\n").concat(s2.slice(0, 5).map((e6) => {
7972
+ await Hy("Please give a complete natal chart interpretation for ".concat(o2, ".\n\nKey planet placements:\n").concat(s2.slice(0, 5).map((e6) => {
7970
7973
  var t3;
7971
7974
  return " \u2022 ".concat(e6.name, " in ").concat((t3 = e6.sign) == null ? "?" : t3).concat(e6.house ? ", House ".concat(e6.house) : "").concat(e6.retrograde ? " \u211E" : "");
7972
7975
  }).join("\n"), "\n\nMajor aspects:\n").concat(c2, "\n\nCover: (1) Core identity and soul purpose (Sun, Moon, Ascendant), (2) The chart's dominant element, modality, and overall signature, (3) The most significant aspects and their psychological themes, (4) Key life areas of focus and challenge, (5) A practical synthesis \u2014 who is this person and what is their path?"));
7973
7976
  }
7974
- async function Uy() {
7977
+ async function Wy() {
7975
7978
  var e5, t2, n2, r2;
7976
7979
  if (!$) return;
7977
7980
  let i2 = $, a2 = (e5 = i2._birth_params) == null ? {} : e5;
7978
- await Vy("I'm exploring the natal chart for ".concat((t2 = (n2 = a2.name) == null ? a2.location : n2) == null ? "this chart" : t2, ". Key placements: ").concat(K_(i2.planets).slice(0, 4).map((e6) => {
7981
+ await Hy("I'm exploring the natal chart for ".concat((t2 = (n2 = a2.name) == null ? a2.location : n2) == null ? "this chart" : t2, ". Key placements: ").concat(K_(i2.planets).slice(0, 4).map((e6) => {
7979
7982
  var t3;
7980
7983
  return "".concat(e6.name, " in ").concat((t3 = e6.sign) == null ? "?" : t3).concat(e6.house ? " H".concat(e6.house) : "");
7981
7984
  }).join(", ") || "unknown placements", ". Major aspects: ").concat(((r2 = i2.aspects) == null ? [] : r2).filter((e6) => {
@@ -7983,7 +7986,7 @@ async function Uy() {
7983
7986
  return ["conjunction", "opposition", "trine", "square", "sextile"].includes((t3 = e6.type) == null ? "" : t3);
7984
7987
  }).slice(0, 5).map((e6) => "".concat(e6.planet1, " ").concat(e6.type, " ").concat(e6.planet2, " (").concat(Number(e6.orb).toFixed(1), "\xB0)")).join(", ") || "none detected", ".\n\nBased on this chart, please suggest 3-4 specific, insightful questions I could ask to understand this person more deeply \u2014 such as how particular placements manifest in real life, the most significant aspect dynamics, or how to integrate the chart's core tensions. Present each as a tappable question I can ask you."));
7985
7988
  }
7986
- async function Wy(e5) {
7989
+ async function Gy(e5) {
7987
7990
  let t2 = "";
7988
7991
  if (e5.type === "planet") {
7989
7992
  var n2;
@@ -8018,7 +8021,7 @@ async function Wy(e5) {
8018
8021
  throw console.error("[ChartWheel] \u274C sendMessage failed:", e6), e6;
8019
8022
  }
8020
8023
  }
8021
- async function Gy(e5) {
8024
+ async function Ky(e5) {
8022
8025
  if (!($ != null && $._birth_params)) {
8023
8026
  Uv(py, yy);
8024
8027
  return;
@@ -8031,21 +8034,21 @@ async function Gy(e5) {
8031
8034
  console.error("[Chart] Recalculate failed:", e6), Uv(py, yy);
8032
8035
  }
8033
8036
  }
8034
- var Ky;
8035
- function qy() {
8036
- Ky && (clearTimeout(Ky), Ky = void 0);
8037
+ var qy;
8038
+ function Jy() {
8039
+ qy && (clearTimeout(qy), qy = void 0);
8037
8040
  }
8038
- function Jy(e5, t2) {
8039
- qy(), ly.setAttribute("hidden", ""), iy({ container: uy, message: e5, onRetry: t2 });
8041
+ function Yy(e5, t2) {
8042
+ Jy(), ly.setAttribute("hidden", ""), iy({ container: uy, message: e5, onRetry: t2 });
8040
8043
  }
8041
- function Yy() {
8042
- qy(), uy.setAttribute("hidden", ""), ly.removeAttribute("hidden"), Ky = setTimeout(() => {
8043
- Jy("The chart didn't load. Tap to try again.", Yy);
8044
+ function Xy() {
8045
+ Jy(), uy.setAttribute("hidden", ""), ly.removeAttribute("hidden"), qy = setTimeout(() => {
8046
+ Yy("The chart didn't load. Tap to try again.", Xy);
8044
8047
  }, 3e4), vy.sendMessage({ role: "user", content: [{ type: "text", text: "Please regenerate the chart wheel." }] }).catch(() => {
8045
8048
  });
8046
8049
  }
8047
- oy(vy, { loadingEl: ly, contentEl: uy, statusFn: Cy, paramControls: () => by }), Ky = setTimeout(() => {
8048
- Jy("Chart data is taking longer than expected.", Yy);
8050
+ oy(vy, { loadingEl: ly, contentEl: uy, statusFn: Cy, paramControls: () => by }), qy = setTimeout(() => {
8051
+ Yy("Chart data is taking longer than expected.", Xy);
8049
8052
  }, 3e4), (async () => {
8050
8053
  try {
8051
8054
  await vy.connect();
@@ -8054,7 +8057,7 @@ oy(vy, { loadingEl: ly, contentEl: uy, statusFn: Cy, paramControls: () => by }),
8054
8057
  $ && wy($);
8055
8058
  }), $ && wy($);
8056
8059
  } catch (e5) {
8057
- console.error("[ChartWheel] \u274C app.connect() FAILED:", e5), Jy("The chart didn't load. Tap to try again.", Yy);
8060
+ console.error("[ChartWheel] \u274C app.connect() FAILED:", e5), Yy("The chart didn't load. Tap to try again.", Xy);
8058
8061
  }
8059
8062
  })();
8060
8063
  </script>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openephemeris/mcp-server",
3
- "version": "4.7.0",
3
+ "version": "4.8.1",
4
4
  "description": "Model Context Protocol server for the Open Ephemeris astronomical computation API",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -41,6 +41,7 @@
41
41
  "check:schema-packs": "tsx scripts/schema-packs.ts --check",
42
42
  "sync:readme": "tsx scripts/sync-readme.ts --write",
43
43
  "check:readme": "tsx scripts/sync-readme.ts --check",
44
+ "check:counts": "tsx scripts/check-counts.ts",
44
45
  "check:pack": "tsx scripts/pack-audit.ts",
45
46
  "regen:plugin": "tsx scripts/plugin-audit.ts --write",
46
47
  "check:plugin": "tsx scripts/plugin-audit.ts --check",
@@ -48,7 +49,8 @@
48
49
  "check:skills": "node scripts/build-skills.mjs --check",
49
50
  "sync:public": "node scripts/sync-public-repo.mjs --write",
50
51
  "check:public": "node scripts/sync-public-repo.mjs --check",
51
- "verify:release": "npm run check:dev-allowlist && npm run check:schema-packs && npm run check:readme && npm run check:skills && npm run check:plugin && npm run check:public && npm run typecheck && npm test && npm run build && npm run check:pack",
52
+ "check:public:strict": "node scripts/sync-public-repo.mjs --check --require-mirror",
53
+ "verify:release": "npm run check:dev-allowlist && npm run check:schema-packs && npm run check:readme && npm run check:counts && npm run check:skills && npm run check:plugin && npm run check:public:strict && npm run typecheck && npm test && npm run build && npm run check:pack",
52
54
  "prepack": "npm run build",
53
55
  "prepublishOnly": "npm run verify:release",
54
56
  "capture:fixtures": "tsx scripts/capture-harness-fixtures.ts"
package/smithery.yaml CHANGED
@@ -7,12 +7,12 @@
7
7
 
8
8
  name: Open Ephemeris
9
9
  description: >
10
- NASA JPL DE440-backed astronomical computation engine for AI agents. 90+ typed tools covering
10
+ NASA JPL DE440-backed astronomical computation engine for AI agents. Typed tools spanning
11
11
  natal charts, transit forecasting, Human Design charts, eclipses, astrocartography power
12
12
  lines, Venus Star Points, electional timing windows, synastry, composite charts, Vedic
13
13
  charts, Chinese BaZi, and more — powered by JPL DE440 ephemerides for sub-arcsecond
14
14
  zero-hallucination accuracy. Includes an LLM-optimized output format
15
- (format=llm) that compresses chart responses by ~50%. Free Explorer tier available.
15
+ (format=llm) that compresses chart responses by 50–73%. Free Explorer tier available.
16
16
  iconUrl: https://mcp.openephemeris.com/icon.png
17
17
  homepage: https://openephemeris.com
18
18
 
@@ -38,7 +38,7 @@ configSchema:
38
38
  - llm
39
39
  description: >
40
40
  Default output format for all tools. 'llm' returns compact,
41
- token-optimized output (~50% smaller). 'json' returns full verbose JSON.
41
+ token-optimized output (50–73% smaller). 'json' returns full verbose JSON.
42
42
  Individual tool calls can override this setting.
43
43
  default: json
44
44
  baseUrl:
@@ -49,6 +49,16 @@ configSchema:
49
49
  default production endpoint (https://api.openephemeris.com). Useful
50
50
  for self-hosted or staging deployments.
51
51
  default: ""
52
+ toolSurface:
53
+ type: string
54
+ title: Tool Surface
55
+ description: >
56
+ Which tools to advertise. Leave blank for the curated default set,
57
+ 'full' for the whole catalog, or a comma list of traditions —
58
+ astrology, moon, hd, bazi, vedic, acg, electional, venus — to pay
59
+ context only for the work you do (e.g. 'hd,bazi'). Every tool stays
60
+ callable by name regardless of surface.
61
+ default: ""
52
62
 
53
63
  # How to start the server locally (stdio transport for Claude Desktop / Cursor)
54
64
  startCommand:
@@ -61,5 +71,6 @@ startCommand:
61
71
  OPENEPHEMERIS_API_KEY: config.apiKey,
62
72
  ...(config.format && config.format !== "json" ? { OPENEPHEMERIS_FORMAT: config.format } : {}),
63
73
  ...(config.baseUrl ? { OPENEPHEMERIS_BACKEND_URL: config.baseUrl } : {}),
74
+ ...(config.toolSurface ? { OPENEPHEMERIS_TOOLS: config.toolSurface } : {}),
64
75
  }
65
76
  })