@openephemeris/mcp-server 3.24.0 → 4.1.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.
Files changed (58) hide show
  1. package/CHANGELOG.md +173 -0
  2. package/LICENSE +21 -21
  3. package/README.md +75 -3
  4. package/dist/analytics.js +37 -5
  5. package/dist/backend/client.d.ts +7 -0
  6. package/dist/backend/client.js +39 -38
  7. package/dist/index.js +64 -2
  8. package/dist/oauth/session-utils.d.ts +42 -18
  9. package/dist/oauth/session-utils.js +79 -0
  10. package/dist/prompts.js +55 -42
  11. package/dist/server-sse.js +114 -14
  12. package/dist/tools/apps/bazi-app.js +15 -28
  13. package/dist/tools/apps/bi-wheel-app.js +14 -11
  14. package/dist/tools/apps/bodygraph-app.d.ts +5 -5
  15. package/dist/tools/apps/bodygraph-app.js +159 -212
  16. package/dist/tools/apps/chart-wheel-app.js +21 -20
  17. package/dist/tools/apps/location-tools.js +167 -18
  18. package/dist/tools/apps/moon-phase-app.js +10 -3
  19. package/dist/tools/apps/transit-timeline-app.js +6 -4
  20. package/dist/tools/apps/vedic-chart-app.js +15 -49
  21. package/dist/tools/datetime.d.ts +65 -0
  22. package/dist/tools/datetime.js +153 -0
  23. package/dist/tools/dev.js +4 -3
  24. package/dist/tools/index.d.ts +45 -2
  25. package/dist/tools/index.js +81 -2
  26. package/dist/tools/specialized/account.d.ts +1 -0
  27. package/dist/tools/specialized/account.js +100 -0
  28. package/dist/tools/specialized/acg.js +16 -14
  29. package/dist/tools/specialized/bazi.d.ts +7 -1
  30. package/dist/tools/specialized/bazi.js +89 -23
  31. package/dist/tools/specialized/bi_wheel.js +5 -4
  32. package/dist/tools/specialized/chart_wheel.js +5 -8
  33. package/dist/tools/specialized/comparative.js +40 -21
  34. package/dist/tools/specialized/electional.js +13 -10
  35. package/dist/tools/specialized/ephemeris_core.js +13 -8
  36. package/dist/tools/specialized/ephemeris_extended.js +60 -53
  37. package/dist/tools/specialized/hd_bodygraph.js +8 -10
  38. package/dist/tools/specialized/hd_cycles.js +7 -14
  39. package/dist/tools/specialized/hd_group.js +20 -13
  40. package/dist/tools/specialized/human_design.js +11 -17
  41. package/dist/tools/specialized/moon.js +14 -6
  42. package/dist/tools/specialized/natal.js +7 -9
  43. package/dist/tools/specialized/progressed.js +12 -8
  44. package/dist/tools/specialized/relocation.js +9 -3
  45. package/dist/tools/specialized/returns.js +23 -11
  46. package/dist/tools/specialized/synastry.js +17 -6
  47. package/dist/tools/specialized/transits.js +9 -5
  48. package/dist/tools/specialized/vedic.js +5 -3
  49. package/dist/tools/specialized/venus_star_points.js +14 -9
  50. package/dist/ui/bazi.html +1063 -1049
  51. package/dist/ui/bi-wheel.html +4188 -4128
  52. package/dist/ui/bodygraph.html +3673 -3616
  53. package/dist/ui/chart-wheel.html +3769 -3713
  54. package/dist/ui/moon-phase.html +3219 -3153
  55. package/dist/ui/transit-timeline.html +199 -170
  56. package/dist/ui/vedic-chart.html +1116 -1098
  57. package/package.json +3 -2
  58. package/smithery.yaml +1 -1
@@ -1,6 +1,7 @@
1
1
  import { registerTool, validateRequired } from "../index.js";
2
2
  import { getActiveClient } from "../../backend/client.js";
3
3
  import { OUTPUT_SCHEMA_JSON } from "../output-schemas.js";
4
+ import { DATETIME_DESC, TIMEZONE_PROPERTY, assertZonedDatetime } from "../datetime.js";
4
5
  registerTool({
5
6
  name: "ephemeris_relocation",
6
7
  description: "Calculate a relocation chart — the same natal planetary positions re-cast for a different " +
@@ -8,18 +9,20 @@ registerTool({
8
9
  "and angles, without changing the planetary longitudes in the chart.\n\n" +
9
10
  "CREDIT COST: 1 credit per call.\n\n" +
10
11
  "EXAMPLE: How does moving from Chicago to London change someone's chart?\n" +
11
- " natal_datetime='1990-04-15T14:30:00', natal_latitude=41.8781, natal_longitude=-87.6298,\n" +
12
+ " natal_datetime='1990-04-15T14:30:00', timezone='America/Chicago',\n" +
13
+ " natal_latitude=41.8781, natal_longitude=-87.6298,\n" +
12
14
  " relocation_latitude=51.5074, relocation_longitude=-0.1278",
13
15
  inputSchema: {
14
16
  type: "object",
15
17
  properties: {
16
18
  natal_datetime: {
17
19
  type: "string",
18
- description: "ISO 8601 birth datetime (local time at birth location).",
20
+ description: DATETIME_DESC,
19
21
  },
22
+ timezone: TIMEZONE_PROPERTY,
20
23
  natal_latitude: {
21
24
  type: "number",
22
- description: "Latitude of birth location in decimal degrees.",
25
+ description: "Latitude of birth location in decimal degrees. Resolve from a place name with location_search; never recall coordinates from memory.",
23
26
  },
24
27
  natal_longitude: {
25
28
  type: "number",
@@ -51,6 +54,7 @@ registerTool({
51
54
  annotations: { title: "Relocation Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
52
55
  handler: async (args) => {
53
56
  validateRequired(args, ["natal_datetime", "natal_latitude", "natal_longitude", "relocation_latitude", "relocation_longitude"]);
57
+ assertZonedDatetime("natal_datetime", args.natal_datetime, args.timezone);
54
58
  const body = {
55
59
  natal: {
56
60
  subject: {
@@ -59,6 +63,8 @@ registerTool({
59
63
  birth_location: {
60
64
  latitude: { decimal: args.natal_latitude },
61
65
  longitude: { decimal: args.natal_longitude },
66
+ // The server resolves the IANA zone, so historical DST stays correct.
67
+ ...(args.timezone ? { timezone: { iana_name: args.timezone } } : {}),
62
68
  },
63
69
  },
64
70
  },
@@ -1,6 +1,7 @@
1
1
  import { registerTool, validateRequired } from "../index.js";
2
2
  import { getActiveClient } from "../../backend/client.js";
3
- import { OUTPUT_SCHEMA_IMAGE_AND_JSON } from "../output-schemas.js";
3
+ import { OUTPUT_SCHEMA_IMAGE_AND_JSON, OUTPUT_SCHEMA_JSON } from "../output-schemas.js";
4
+ import { DATETIME_DESC, TIMEZONE_PROPERTY, assertZonedDatetime, localToUtcIso } from "../datetime.js";
4
5
  // POST /predictive/returns/solar
5
6
  registerTool({
6
7
  name: "ephemeris_solar_return",
@@ -18,8 +19,9 @@ registerTool({
18
19
  properties: {
19
20
  birth_datetime: {
20
21
  type: "string",
21
- description: "ISO 8601 birth date/time. Include offset or Z (e.g. '1985-06-21T14:00:00-05:00').",
22
+ description: DATETIME_DESC,
22
23
  },
24
+ timezone: TIMEZONE_PROPERTY,
23
25
  target_datetime: {
24
26
  type: "string",
25
27
  description: "Date/time near which to find the Solar Return (ISO 8601 with offset or Z). " +
@@ -64,11 +66,13 @@ registerTool({
64
66
  annotations: { title: "Solar Return", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
65
67
  handler: async (args) => {
66
68
  validateRequired(args, ["birth_datetime"]);
69
+ assertZonedDatetime("birth_datetime", args.birth_datetime, args.timezone);
70
+ assertZonedDatetime("target_datetime", args.target_datetime, args.timezone);
67
71
  // Default target to current year if not provided
68
72
  const targetDt = args.target_datetime ?? new Date().toISOString();
69
73
  const body = {
70
- birth_datetime: { iso: args.birth_datetime },
71
- target_datetime: { iso: targetDt },
74
+ birth_datetime: { iso: localToUtcIso("birth_datetime", args.birth_datetime, args.timezone) },
75
+ target_datetime: { iso: localToUtcIso("target_datetime", targetDt, args.timezone) },
72
76
  };
73
77
  if (args.birth_latitude != null && args.birth_longitude != null) {
74
78
  body.location = {
@@ -110,8 +114,9 @@ registerTool({
110
114
  properties: {
111
115
  birth_datetime: {
112
116
  type: "string",
113
- description: "ISO 8601 birth date/time. Include offset or Z.",
117
+ description: DATETIME_DESC,
114
118
  },
119
+ timezone: TIMEZONE_PROPERTY,
115
120
  target_datetime: {
116
121
  type: "string",
117
122
  description: "Date/time near which to find the Lunar Return (ISO 8601 with offset or Z). " +
@@ -129,14 +134,17 @@ registerTool({
129
134
  required: ["birth_datetime"],
130
135
  additionalProperties: false,
131
136
  },
132
- outputSchema: OUTPUT_SCHEMA_IMAGE_AND_JSON,
137
+ // JSON only: this tool never sets include_visual, so it cannot return an image.
138
+ outputSchema: OUTPUT_SCHEMA_JSON,
133
139
  annotations: { title: "Lunar Return", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
134
140
  handler: async (args) => {
135
141
  validateRequired(args, ["birth_datetime"]);
142
+ assertZonedDatetime("birth_datetime", args.birth_datetime, args.timezone);
143
+ assertZonedDatetime("target_datetime", args.target_datetime, args.timezone);
136
144
  const targetDt = args.target_datetime ?? new Date().toISOString();
137
145
  const body = {
138
- birth_datetime: { iso: args.birth_datetime },
139
- target_datetime: { iso: targetDt },
146
+ birth_datetime: { iso: localToUtcIso("birth_datetime", args.birth_datetime, args.timezone) },
147
+ target_datetime: { iso: localToUtcIso("target_datetime", targetDt, args.timezone) },
140
148
  };
141
149
  if (args.birth_latitude != null && args.birth_longitude != null) {
142
150
  body.location = {
@@ -167,15 +175,16 @@ registerTool({
167
175
  },
168
176
  birth_datetime: {
169
177
  type: "string",
170
- description: "ISO 8601 birth date/time. MUST include offset or Z.",
178
+ description: DATETIME_DESC,
171
179
  },
180
+ timezone: TIMEZONE_PROPERTY,
172
181
  target_datetime: {
173
182
  type: "string",
174
183
  description: "Date/time near which to find the return (ISO 8601). MUST include offset or Z. Required.",
175
184
  },
176
185
  birth_latitude: {
177
186
  type: "number",
178
- description: "Birth latitude in decimal degrees. Required to get a full return chart (house cusps, angles).",
187
+ description: "Birth latitude in decimal degrees. Required to get a full return chart (house cusps, angles). Resolve from a place name with location_search; never recall coordinates from memory.",
179
188
  },
180
189
  birth_longitude: {
181
190
  type: "number",
@@ -185,10 +194,13 @@ registerTool({
185
194
  required: ["body", "birth_datetime", "target_datetime"],
186
195
  additionalProperties: false,
187
196
  },
188
- outputSchema: OUTPUT_SCHEMA_IMAGE_AND_JSON,
197
+ // JSON only: this tool never sets include_visual, so it cannot return an image.
198
+ outputSchema: OUTPUT_SCHEMA_JSON,
189
199
  annotations: { title: "Planetary Return", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
190
200
  handler: async (args) => {
191
201
  validateRequired(args, ["body", "birth_datetime", "target_datetime"]);
202
+ assertZonedDatetime("birth_datetime", args.birth_datetime, args.timezone);
203
+ assertZonedDatetime("target_datetime", args.target_datetime, args.timezone);
192
204
  const requestBody = {
193
205
  body: args.body,
194
206
  birth_datetime: { iso: args.birth_datetime },
@@ -1,22 +1,27 @@
1
1
  import { registerTool, validateRequired } from "../index.js";
2
2
  import { getActiveClient } from "../../backend/client.js";
3
3
  import { OUTPUT_SCHEMA_IMAGE_AND_JSON } from "../output-schemas.js";
4
+ import { DATETIME_DESC, assertZonedDatetime, timezoneProperty } from "../datetime.js";
4
5
  registerTool({
5
6
  name: "ephemeris_synastry",
6
7
  description: "Calculate a synastry chart comparing two people's natal charts. Returns inter-aspects " +
7
8
  "(planetary connections between the two charts), composite points, and relationship indicators. " +
8
9
  "Use this for compatibility analysis, relationship timing, or partnership insights.\n\n" +
9
10
  "CREDIT COST: 3 credits per call.\n\n" +
10
- "EXAMPLE: Compare two people's charts:\n" +
11
- " person_a_datetime='1990-04-15T14:30:00', person_a_latitude=41.8781, person_a_longitude=-87.6298,\n" +
12
- " person_b_datetime='1988-09-22T08:15:00', person_b_latitude=34.0522, person_b_longitude=-118.2437",
11
+ "EXAMPLE: Compare two people's charts (local birth times, each with its zone):\n" +
12
+ " person_a_datetime='1990-04-15T14:30:00', person_a_timezone='America/Chicago',\n" +
13
+ " person_a_latitude=41.8781, person_a_longitude=-87.6298,\n" +
14
+ " person_b_datetime='1988-09-22T08:15:00', person_b_timezone='America/Los_Angeles',\n" +
15
+ " person_b_latitude=34.0522, person_b_longitude=-118.2437",
13
16
  inputSchema: {
14
17
  type: "object",
15
18
  properties: {
16
- person_a_datetime: { type: "string", description: "Person A birth datetime (ISO 8601)." },
17
- person_a_latitude: { type: "number", description: "Person A birth latitude." },
19
+ person_a_datetime: { type: "string", description: DATETIME_DESC },
20
+ person_a_timezone: timezoneProperty("Person A's birth location"),
21
+ person_a_latitude: { type: "number", description: "Person A birth latitude. Resolve from a place name with location_search; never recall coordinates from memory." },
18
22
  person_a_longitude: { type: "number", description: "Person A birth longitude." },
19
- person_b_datetime: { type: "string", description: "Person B birth datetime (ISO 8601)." },
23
+ person_b_datetime: { type: "string", description: DATETIME_DESC },
24
+ person_b_timezone: timezoneProperty("Person B's birth location", "America/Los_Angeles"),
20
25
  person_b_latitude: { type: "number", description: "Person B birth latitude." },
21
26
  person_b_longitude: { type: "number", description: "Person B birth longitude." },
22
27
  house_system: {
@@ -58,6 +63,8 @@ registerTool({
58
63
  "person_a_datetime", "person_a_latitude", "person_a_longitude",
59
64
  "person_b_datetime", "person_b_latitude", "person_b_longitude",
60
65
  ]);
66
+ assertZonedDatetime("person_a_datetime", args.person_a_datetime, args.person_a_timezone, "person_a_timezone");
67
+ assertZonedDatetime("person_b_datetime", args.person_b_datetime, args.person_b_timezone, "person_b_timezone");
61
68
  const body = {
62
69
  subject_a: {
63
70
  name: "Person A",
@@ -65,6 +72,9 @@ registerTool({
65
72
  birth_location: {
66
73
  latitude: { decimal: args.person_a_latitude },
67
74
  longitude: { decimal: args.person_a_longitude },
75
+ // The server resolves the zone; sending the IANA name keeps
76
+ // historical DST correct instead of resolving it here.
77
+ ...(args.person_a_timezone ? { timezone: { iana_name: args.person_a_timezone } } : {}),
68
78
  },
69
79
  },
70
80
  subject_b: {
@@ -73,6 +83,7 @@ registerTool({
73
83
  birth_location: {
74
84
  latitude: { decimal: args.person_b_latitude },
75
85
  longitude: { decimal: args.person_b_longitude },
86
+ ...(args.person_b_timezone ? { timezone: { iana_name: args.person_b_timezone } } : {}),
76
87
  },
77
88
  },
78
89
  };
@@ -1,6 +1,7 @@
1
1
  import { registerTool, validateRequired } from "../index.js";
2
2
  import { getActiveClient } from "../../backend/client.js";
3
3
  import { OUTPUT_SCHEMA_JSON } from "../output-schemas.js";
4
+ import { DATETIME_DESC, WINDOW_DATE_DESC, timezoneProperty } from "../datetime.js";
4
5
  registerTool({
5
6
  name: "ephemeris_transits",
6
7
  description: "Search for astrological transit events affecting a natal chart over a date range. " +
@@ -22,11 +23,12 @@ registerTool({
22
23
  properties: {
23
24
  natal_datetime: {
24
25
  type: "string",
25
- description: "ISO 8601 birth datetime for the natal chart.",
26
+ description: DATETIME_DESC,
26
27
  },
28
+ natal_timezone: timezoneProperty("the natal birth location"),
27
29
  natal_latitude: {
28
30
  type: "number",
29
- description: "Latitude of birth location in decimal degrees.",
31
+ description: "Latitude of birth location in decimal degrees. Resolve from a place name with location_search; never recall coordinates from memory.",
30
32
  },
31
33
  natal_longitude: {
32
34
  type: "number",
@@ -34,11 +36,11 @@ registerTool({
34
36
  },
35
37
  start_date: {
36
38
  type: "string",
37
- description: "Start of the transit search window, ISO 8601 date or datetime (e.g. '2026-01-01').",
39
+ description: "Start of the transit search window. " + WINDOW_DATE_DESC,
38
40
  },
39
41
  end_date: {
40
42
  type: "string",
41
- description: "End of the transit search window, ISO 8601 date or datetime (e.g. '2026-06-30').",
43
+ description: "End of the transit search window. " + WINDOW_DATE_DESC,
42
44
  },
43
45
  transiting_planets: {
44
46
  type: "array",
@@ -72,7 +74,9 @@ registerTool({
72
74
  birth_datetime: { iso: args.natal_datetime },
73
75
  birth_location: {
74
76
  latitude: { decimal: args.natal_latitude },
75
- longitude: { decimal: args.natal_longitude }
77
+ longitude: { decimal: args.natal_longitude },
78
+ // The server resolves the IANA zone, so historical DST stays correct.
79
+ ...(args.natal_timezone ? { timezone: { iana_name: args.natal_timezone } } : {}),
76
80
  },
77
81
  },
78
82
  };
@@ -1,6 +1,7 @@
1
1
  import { registerTool, validateRequired, validateCoordinates } from "../index.js";
2
2
  import { getActiveClient } from "../../backend/client.js";
3
3
  import { OUTPUT_SCHEMA_JSON } from "../output-schemas.js";
4
+ import { DATETIME_DESC, TIMEZONE_PROPERTY, localToUtcIso } from "../datetime.js";
4
5
  registerTool({
5
6
  name: "vedic_chart",
6
7
  description: "Calculate a Vedic (Jyotish) natal chart with sidereal positions. Returns planet placements " +
@@ -15,11 +16,12 @@ registerTool({
15
16
  properties: {
16
17
  datetime: {
17
18
  type: "string",
18
- description: "ISO 8601 birth datetime in UTC, e.g. '1990-01-15T08:30:00Z'. Include 'Z' or timezone offset.",
19
+ description: DATETIME_DESC,
19
20
  },
21
+ timezone: TIMEZONE_PROPERTY,
20
22
  latitude: {
21
23
  type: "number",
22
- description: "Birth latitude in decimal degrees (north positive).",
24
+ description: "Birth latitude in decimal degrees (north positive). Resolve from a place name with location_search; never recall coordinates from memory.",
23
25
  },
24
26
  longitude: {
25
27
  type: "number",
@@ -40,7 +42,7 @@ registerTool({
40
42
  validateRequired(args, ["datetime", "latitude", "longitude"]);
41
43
  validateCoordinates(args, "latitude", "longitude");
42
44
  const body = {
43
- datetime_utc: args.datetime,
45
+ datetime_utc: localToUtcIso("datetime", args.datetime, args.timezone),
44
46
  latitude: args.latitude,
45
47
  longitude: args.longitude,
46
48
  };
@@ -1,13 +1,16 @@
1
1
  import { registerTool, validateRequired } from "../index.js";
2
2
  import { getActiveClient } from "../../backend/client.js";
3
3
  import { OUTPUT_SCHEMA_JSON } from "../output-schemas.js";
4
- function buildSubject(datetime, lat, lon) {
4
+ import { DATETIME_DESC, TIMEZONE_PROPERTY, assertZonedDatetime } from "../datetime.js";
5
+ function buildSubject(datetime, lat, lon, timezone) {
5
6
  return {
6
7
  name: "Subject",
7
8
  birth_datetime: { iso: datetime },
8
9
  birth_location: {
9
10
  latitude: { decimal: lat },
10
11
  longitude: { decimal: lon },
12
+ // The server resolves the IANA zone, so historical DST stays correct.
13
+ ...(timezone ? { timezone: { iana_name: timezone } } : {}),
11
14
  },
12
15
  };
13
16
  }
@@ -16,13 +19,14 @@ registerTool({
16
19
  name: "venus_star_points",
17
20
  description: "Get Venus Star Points — the Sun-Venus conjunction events nearest to a birth date. " +
18
21
  "Shows the quality of each conjunction (cazimi, combust, under beams) with zodiac details.\n\n" +
19
- "CREDIT COST: 2 credits per call.\n\n" +
22
+ "CREDIT COST: 1 credit per call.\n\n" +
20
23
  "EXAMPLE: Venus star points for someone born 1990-04-15:\n" +
21
- " datetime='1990-04-15T14:30:00', latitude=41.88, longitude=-87.63",
24
+ " datetime='1990-04-15T14:30:00', timezone='America/Chicago', latitude=41.88, longitude=-87.63",
22
25
  inputSchema: {
23
26
  type: "object",
24
27
  properties: {
25
- datetime: { type: "string", description: "Birth datetime (ISO 8601)." },
28
+ datetime: { type: "string", description: DATETIME_DESC },
29
+ timezone: TIMEZONE_PROPERTY,
26
30
  latitude: { type: "number", description: "Birth latitude." },
27
31
  longitude: { type: "number", description: "Birth longitude." },
28
32
  format: { type: "string", enum: ["json", "llm"], description: "Output format." },
@@ -34,11 +38,12 @@ registerTool({
34
38
  annotations: { title: "Venus Star Points", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
35
39
  handler: async (args) => {
36
40
  validateRequired(args, ["datetime", "latitude", "longitude"]);
41
+ assertZonedDatetime("datetime", args.datetime, args.timezone);
37
42
  const query = {};
38
43
  if (args.format)
39
44
  query.format = args.format;
40
45
  return await getActiveClient().request("POST", "/ephemeris/venus-star-points", {
41
- data: { subject: buildSubject(args.datetime, args.latitude, args.longitude) },
46
+ data: { subject: buildSubject(args.datetime, args.latitude, args.longitude, args.timezone) },
42
47
  params: query,
43
48
  });
44
49
  },
@@ -48,7 +53,7 @@ registerTool({
48
53
  name: "venus_star_points_conjunctions",
49
54
  description: "Find all Sun-Venus conjunctions in a date range. Returns each conjunction with " +
50
55
  "its exact timestamp, zodiac position, orb, visibility (morning/evening star), and dignity.\n\n" +
51
- "CREDIT COST: 2 credits per call.\n\n" +
56
+ "CREDIT COST: 1 credit per call.\n\n" +
52
57
  "EXAMPLE: Find Venus conjunctions in 2026:\n" +
53
58
  " start_date='2026-01-01', end_date='2026-12-31'",
54
59
  inputSchema: {
@@ -80,7 +85,7 @@ registerTool({
80
85
  description: "Compute the 8-year Venus Star pattern — the pentagram of 5 Venus-Sun conjunctions " +
81
86
  "that trace a near-perfect star over 8 years (the Venus synodic cycle). Returns the 5 " +
82
87
  "vertices with their zodiac positions.\n\n" +
83
- "CREDIT COST: 2 credits per call.\n\n" +
88
+ "CREDIT COST: 1 credit per call.\n\n" +
84
89
  "EXAMPLE: 8-year star starting from 2020:\n" +
85
90
  " date='2020-01-01'",
86
91
  inputSchema: {
@@ -141,7 +146,7 @@ registerTool({
141
146
  name: "venus_elongations",
142
147
  description: "Find Venus greatest elongation events (when Venus is farthest from the Sun in the sky). " +
143
148
  "Returns east (evening star) and west (morning star) elongation peaks.\n\n" +
144
- "CREDIT COST: 2 credits per call.",
149
+ "CREDIT COST: 1 credit per call.",
145
150
  inputSchema: {
146
151
  type: "object",
147
152
  properties: {
@@ -170,7 +175,7 @@ registerTool({
170
175
  name: "venus_stations",
171
176
  description: "Find Venus retrograde and direct stations in a date range. Returns the exact " +
172
177
  "moment Venus appears to stop and reverse direction.\n\n" +
173
- "CREDIT COST: 2 credits per call.\n\n" +
178
+ "CREDIT COST: 1 credit per call.\n\n" +
174
179
  "EXAMPLE: Venus stations in 2026:\n" +
175
180
  " start_date='2026-01-01', end_date='2026-12-31'",
176
181
  inputSchema: {