@openephemeris/mcp-server 4.14.2 → 4.14.3

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,27 @@ Version numbering follows [Semantic Versioning](https://semver.org/).
7
7
 
8
8
  ---
9
9
 
10
+ ## [4.14.3] — 2026-09-02
11
+
12
+ ### Fixed
13
+ - **`ephemeris_transits` silently dropped requested `asc`/`mc`/`dsc`/`ic` natal points.** The tool
14
+ matched `natal_points` against `/ephemeris/natal-chart`'s angle field names
15
+ (`ascendant`/`midheaven`/`descendant`/`imum_coeli`), which never matched the short forms the
16
+ tool itself documents — so a search for transits to the Ascendant silently returned zero hits,
17
+ with `success: true` and no indication anything was dropped. Added alias resolution both ways,
18
+ plus an `unresolved_points` field so a genuine mismatch surfaces instead of hiding.
19
+ - **`ephemeris_progressed_chart` hardcoded `subject.name` to `"Progressed Subject"`** on both the
20
+ natal and progressed blocks of the response, so no consumer could tell them apart by name. Now
21
+ an optional `name` argument, defaulting to a neutral label.
22
+
23
+ ### Added
24
+ - `/ephemeris/progressed` responses now include `metadata.angle_method`
25
+ (`chart_for_progressed_moment` or `solar_arc_directed`), naming which algorithm produced the
26
+ progressed angles — previously undeclared and silently implied by
27
+ `progression_options.method`, which only ever described planetary progression.
28
+
29
+ ---
30
+
10
31
  ## [4.14.2] — 2026-09-01
11
32
 
12
33
  ### Fixed
@@ -36,6 +36,10 @@ registerTool({
36
36
  enum: ["secondary", "solar_arc", "tertiary"],
37
37
  description: "Progression method. Defaults to 'secondary' (1 day = 1 year).",
38
38
  },
39
+ name: {
40
+ type: "string",
41
+ description: "Optional label for the subject, echoed back in both natal_subject and progressed_subject. Defaults to a generic label if omitted.",
42
+ },
39
43
  include_aspects: {
40
44
  type: "boolean",
41
45
  description: "Whether to include aspect grid in the response. Default false.",
@@ -67,7 +71,10 @@ registerTool({
67
71
  assertZonedDatetime("target_datetime", args.target_datetime);
68
72
  const body = {
69
73
  subject: {
70
- name: "Progressed Subject",
74
+ // Echoed verbatim into both natal_subject.name and progressed_subject.name
75
+ // by the API (same person, two instants) — never a role-specific label
76
+ // like "Progressed Subject", which would be wrong on the natal block.
77
+ name: args.name || "Subject",
71
78
  birth_datetime: { iso: args.birth_datetime },
72
79
  birth_location: {
73
80
  latitude: { decimal: args.birth_latitude },
@@ -96,6 +96,7 @@ registerTool({
96
96
  const wantedPoints = args.natal_points
97
97
  ? new Set(args.natal_points.map((p) => p.toLowerCase()))
98
98
  : CORE_BODIES_DEFAULT;
99
+ const resolvedPoints = new Set();
99
100
  for (const planet of planetArray) {
100
101
  const name = (planet.name || planet.id || "").toLowerCase();
101
102
  const lon = planet.longitude ?? planet.ecliptic_longitude ?? planet.lon;
@@ -105,26 +106,54 @@ registerTool({
105
106
  continue;
106
107
  targetDegrees.push(Math.round(lon * 100) / 100);
107
108
  natalPositionMap[name] = lon;
109
+ resolvedPoints.add(name);
108
110
  }
109
- // Extract angles (ASC, MC) only when explicitly requested
111
+ // Extract angles (ASC, MC, DSC, IC) only when explicitly requested.
112
+ // /ephemeris/natal-chart names these "ascendant", "midheaven", "descendant",
113
+ // "imum_coeli" — but the short forms below are what this tool documents and
114
+ // what natal_points is usually given as, so map both directions or a caller
115
+ // asking for "asc" silently gets nothing back (no error, no natal_positions
116
+ // entry) even though the point exists in the natal chart.
110
117
  if (args.natal_points) {
118
+ const ANGLE_ALIASES = {
119
+ ascendant: "asc",
120
+ asc: "ascendant",
121
+ midheaven: "mc",
122
+ mc: "midheaven",
123
+ descendant: "dsc",
124
+ dsc: "descendant",
125
+ desc: "descendant",
126
+ imum_coeli: "ic",
127
+ ic: "imum_coeli",
128
+ };
111
129
  const angles = natalResult?.angles || natalResult?.data?.angles;
112
130
  if (angles) {
113
131
  const angleEntries = Array.isArray(angles)
114
132
  ? angles
115
133
  : Object.entries(angles).map(([k, v]) => ({ name: k, ...(typeof v === "object" ? v : { longitude: v }) }));
116
134
  for (const angle of angleEntries) {
117
- const name = (angle.name || angle.id || "").toLowerCase();
135
+ const apiName = (angle.name || angle.id || "").toLowerCase();
118
136
  const lon = angle.longitude ?? angle.ecliptic_longitude ?? angle.lon;
119
137
  if (typeof lon !== "number" || !isFinite(lon))
120
138
  continue;
121
- if (!wantedPoints.has(name))
139
+ const matchedAs = wantedPoints.has(apiName)
140
+ ? apiName
141
+ : (ANGLE_ALIASES[apiName] && wantedPoints.has(ANGLE_ALIASES[apiName]))
142
+ ? ANGLE_ALIASES[apiName]
143
+ : null;
144
+ if (!matchedAs)
122
145
  continue;
123
146
  targetDegrees.push(Math.round(lon * 100) / 100);
124
- natalPositionMap[name] = lon;
147
+ natalPositionMap[matchedAs] = lon;
148
+ resolvedPoints.add(matchedAs);
125
149
  }
126
150
  }
127
151
  }
152
+ // Any requested point that never turned up in natal-chart planets or angles —
153
+ // surface it instead of silently returning fewer targets than asked for.
154
+ const unresolvedPoints = args.natal_points
155
+ ? args.natal_points.filter((p) => !resolvedPoints.has(p.toLowerCase()))
156
+ : [];
128
157
  // Hard cap: never send more than 12 target degrees
129
158
  const MAX_TARGETS = 12;
130
159
  if (targetDegrees.length > MAX_TARGETS) {
@@ -162,6 +191,7 @@ registerTool({
162
191
  // Return combined context so the LLM knows what natal positions were targeted
163
192
  return {
164
193
  natal_positions: natalPositionMap,
194
+ ...(unresolvedPoints.length > 0 ? { unresolved_points: unresolvedPoints } : {}),
165
195
  target_degrees_used: effectiveTargets,
166
196
  aspect_angle: args.aspect_angle ?? 0,
167
197
  transit_results: transitResult,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openephemeris/mcp-server",
3
- "version": "4.14.2",
3
+ "version": "4.14.3",
4
4
  "description": "Model Context Protocol server for the Open Ephemeris astronomical computation API",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",