@openephemeris/mcp-server 3.13.9 → 3.14.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 +39 -0
- package/README.md +3 -3
- package/config/dev-allowlist.json +28 -4
- package/dist/index.js +20 -13
- package/dist/oauth/dcr.d.ts +11 -0
- package/dist/oauth/dcr.js +49 -0
- package/dist/oauth/discovery.d.ts +12 -0
- package/dist/oauth/discovery.js +45 -0
- package/dist/oauth/pkce.d.ts +18 -0
- package/dist/oauth/pkce.js +34 -0
- package/dist/oauth/rate-limit.d.ts +20 -0
- package/dist/oauth/rate-limit.js +65 -0
- package/dist/oauth/store.d.ts +88 -0
- package/dist/oauth/store.js +361 -0
- package/dist/oauth/supabase-jwt.d.ts +39 -0
- package/dist/oauth/supabase-jwt.js +194 -0
- package/dist/oauth/token.d.ts +21 -0
- package/dist/oauth/token.js +215 -0
- package/dist/prompts.js +180 -159
- package/dist/server-sse.js +154 -49
- package/dist/tools/apps/bazi-app.d.ts +23 -0
- package/dist/tools/apps/bazi-app.js +226 -0
- package/dist/tools/apps/bi-wheel-app.d.ts +14 -7
- package/dist/tools/apps/bi-wheel-app.js +347 -113
- package/dist/tools/apps/bodygraph-app.js +106 -13
- package/dist/tools/apps/chart-wheel-app.js +53 -4
- package/dist/tools/apps/location-tools.js +3 -0
- package/dist/tools/apps/moon-phase-app.d.ts +19 -0
- package/dist/tools/apps/moon-phase-app.js +244 -0
- package/dist/tools/apps/transit-timeline-app.d.ts +20 -0
- package/dist/tools/apps/transit-timeline-app.js +295 -0
- package/dist/tools/apps/vedic-chart-app.d.ts +17 -0
- package/dist/tools/apps/vedic-chart-app.js +228 -0
- package/dist/tools/auth.js +4 -0
- package/dist/tools/dev.js +3 -0
- package/dist/tools/index.d.ts +6 -0
- package/dist/tools/index.js +9 -4
- package/dist/tools/output-schemas.d.ts +37 -0
- package/dist/tools/output-schemas.js +130 -0
- package/dist/tools/specialized/acg.js +5 -2
- package/dist/tools/specialized/bazi.js +375 -44
- package/dist/tools/specialized/bi_wheel.js +3 -1
- package/dist/tools/specialized/chart_wheel.js +3 -1
- package/dist/tools/specialized/comparative.js +9 -4
- package/dist/tools/specialized/eclipse.js +3 -1
- package/dist/tools/specialized/electional.js +9 -4
- package/dist/tools/specialized/ephemeris_core.js +5 -2
- package/dist/tools/specialized/ephemeris_extended.js +17 -8
- package/dist/tools/specialized/hd_bodygraph.js +3 -1
- package/dist/tools/specialized/hd_cycles.js +5 -2
- package/dist/tools/specialized/hd_group.js +5 -2
- package/dist/tools/specialized/human_design.js +3 -1
- package/dist/tools/specialized/moon.js +5 -2
- package/dist/tools/specialized/natal.js +3 -1
- package/dist/tools/specialized/progressed.js +3 -1
- package/dist/tools/specialized/relocation.js +3 -1
- package/dist/tools/specialized/returns.js +7 -3
- package/dist/tools/specialized/synastry.js +3 -1
- package/dist/tools/specialized/transits.js +53 -44
- package/dist/tools/specialized/vedic.js +3 -1
- package/dist/tools/specialized/venus_star_points.js +13 -6
- package/dist/ui/bazi.html +213 -0
- package/dist/ui/bi-wheel.html +3714 -3048
- package/dist/ui/bodygraph.html +1952 -1766
- package/dist/ui/chart-wheel.html +3431 -2964
- package/dist/ui/moon-phase.html +6764 -0
- package/dist/ui/transit-timeline.html +6874 -0
- package/dist/ui/vedic-chart.html +210 -0
- package/package.json +15 -12
- package/smithery.yaml +16 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { registerTool, validateRequired } from "../index.js";
|
|
2
2
|
import { getActiveClient } from "../../backend/client.js";
|
|
3
|
+
import { OUTPUT_SCHEMA_IMAGE } from "../output-schemas.js";
|
|
3
4
|
const DATETIME_DESC = "ISO 8601 datetime string, e.g. '1990-04-15T14:30:00' (local time at birth location). " +
|
|
4
5
|
"Include timezone offset if known, e.g. '1990-04-15T14:30:00-05:00'.";
|
|
5
6
|
const HOUSE_SYSTEM_MAP = {
|
|
@@ -46,7 +47,8 @@ registerTool({
|
|
|
46
47
|
required: ["datetime", "latitude", "longitude"],
|
|
47
48
|
additionalProperties: false,
|
|
48
49
|
},
|
|
49
|
-
|
|
50
|
+
outputSchema: OUTPUT_SCHEMA_IMAGE,
|
|
51
|
+
annotations: { title: "Chart Wheel SVG", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
50
52
|
handler: async (args) => {
|
|
51
53
|
validateRequired(args, ["datetime", "latitude", "longitude"]);
|
|
52
54
|
const body = {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { registerTool, validateRequired } from "../index.js";
|
|
2
2
|
import { getActiveClient } from "../../backend/client.js";
|
|
3
|
+
import { OUTPUT_SCHEMA_JSON } from "../output-schemas.js";
|
|
3
4
|
function buildSubject(name, datetime, lat, lon, timezone) {
|
|
4
5
|
const subj = {
|
|
5
6
|
name,
|
|
@@ -42,7 +43,8 @@ registerTool({
|
|
|
42
43
|
],
|
|
43
44
|
additionalProperties: false,
|
|
44
45
|
},
|
|
45
|
-
|
|
46
|
+
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
47
|
+
annotations: { title: "Davison Relationship Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
46
48
|
handler: async (args) => {
|
|
47
49
|
validateRequired(args, [
|
|
48
50
|
"person_a_datetime", "person_a_latitude", "person_a_longitude",
|
|
@@ -87,7 +89,8 @@ registerTool({
|
|
|
87
89
|
],
|
|
88
90
|
additionalProperties: false,
|
|
89
91
|
},
|
|
90
|
-
|
|
92
|
+
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
93
|
+
annotations: { title: "Midpoint Composite Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
91
94
|
handler: async (args) => {
|
|
92
95
|
validateRequired(args, [
|
|
93
96
|
"person_a_datetime", "person_a_latitude", "person_a_longitude",
|
|
@@ -132,7 +135,8 @@ registerTool({
|
|
|
132
135
|
],
|
|
133
136
|
additionalProperties: false,
|
|
134
137
|
},
|
|
135
|
-
|
|
138
|
+
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
139
|
+
annotations: { title: "Planet Compatibility Score", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
136
140
|
handler: async (args) => {
|
|
137
141
|
validateRequired(args, [
|
|
138
142
|
"person_a_datetime", "person_a_latitude", "person_a_longitude",
|
|
@@ -174,7 +178,8 @@ registerTool({
|
|
|
174
178
|
required: ["natal_datetime", "natal_latitude", "natal_longitude"],
|
|
175
179
|
additionalProperties: false,
|
|
176
180
|
},
|
|
177
|
-
|
|
181
|
+
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
182
|
+
annotations: { title: "Composite Chart Aspects", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
178
183
|
handler: async (args) => {
|
|
179
184
|
validateRequired(args, ["natal_datetime", "natal_latitude", "natal_longitude"]);
|
|
180
185
|
// Backend expects: { subject: {...}, transit_datetime?: {...} }
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { registerTool, validateRequired, validateCoordinates } from "../index.js";
|
|
2
2
|
import { getActiveClient } from "../../backend/client.js";
|
|
3
|
+
import { OUTPUT_SCHEMA_JSON } from "../output-schemas.js";
|
|
3
4
|
registerTool({
|
|
4
5
|
name: "ephemeris_next_eclipse",
|
|
5
6
|
description: "Find the next solar or lunar eclipse. " +
|
|
@@ -40,7 +41,8 @@ registerTool({
|
|
|
40
41
|
required: ["eclipse_type"],
|
|
41
42
|
additionalProperties: false,
|
|
42
43
|
},
|
|
43
|
-
|
|
44
|
+
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
45
|
+
annotations: { title: "Eclipse Finder", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
44
46
|
handler: async (args) => {
|
|
45
47
|
validateRequired(args, ["eclipse_type"]);
|
|
46
48
|
validateCoordinates(args, "latitude", "longitude");
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { registerTool, validateRequired } from "../index.js";
|
|
2
2
|
import { getActiveClient } from "../../backend/client.js";
|
|
3
|
+
import { OUTPUT_SCHEMA_JSON } from "../output-schemas.js";
|
|
3
4
|
// All electional endpoints are GET endpoints with query params.
|
|
4
5
|
// GET /electional/find-window — already existed, keeping it
|
|
5
6
|
registerTool({
|
|
@@ -56,7 +57,8 @@ registerTool({
|
|
|
56
57
|
required: ["start_date", "end_date", "latitude", "longitude"],
|
|
57
58
|
additionalProperties: false,
|
|
58
59
|
},
|
|
59
|
-
|
|
60
|
+
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
61
|
+
annotations: { title: "Electional Timing Window", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
60
62
|
handler: async (args) => {
|
|
61
63
|
validateRequired(args, ["start_date", "end_date", "latitude", "longitude"]);
|
|
62
64
|
const query = {
|
|
@@ -106,7 +108,8 @@ registerTool({
|
|
|
106
108
|
required: [],
|
|
107
109
|
additionalProperties: false,
|
|
108
110
|
},
|
|
109
|
-
|
|
111
|
+
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
112
|
+
annotations: { title: "Moment Quality Analysis", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
110
113
|
handler: async (args) => {
|
|
111
114
|
const query = {};
|
|
112
115
|
if (args.date)
|
|
@@ -157,7 +160,8 @@ registerTool({
|
|
|
157
160
|
required: [],
|
|
158
161
|
additionalProperties: false,
|
|
159
162
|
},
|
|
160
|
-
|
|
163
|
+
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
164
|
+
annotations: { title: "Retrograde Station Tracker", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
161
165
|
handler: async (args) => {
|
|
162
166
|
const query = {};
|
|
163
167
|
// Map human-readable planet names to IDs if needed
|
|
@@ -216,7 +220,8 @@ registerTool({
|
|
|
216
220
|
required: [],
|
|
217
221
|
additionalProperties: false,
|
|
218
222
|
},
|
|
219
|
-
|
|
223
|
+
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
224
|
+
annotations: { title: "Active Aspects Search", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
220
225
|
handler: async (args) => {
|
|
221
226
|
const query = {};
|
|
222
227
|
if (args.date)
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { registerTool, validateRequired } from "../index.js";
|
|
2
2
|
import { getActiveClient } from "../../backend/client.js";
|
|
3
|
+
import { OUTPUT_SCHEMA_JSON } from "../output-schemas.js";
|
|
3
4
|
// POST /ephemeris/planet-position — OE-016
|
|
4
5
|
registerTool({
|
|
5
6
|
name: "ephemeris_planet_position",
|
|
@@ -34,7 +35,8 @@ registerTool({
|
|
|
34
35
|
required: ["planet_id", "datetime"],
|
|
35
36
|
additionalProperties: false,
|
|
36
37
|
},
|
|
37
|
-
|
|
38
|
+
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
39
|
+
annotations: { title: "Planet Position", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
38
40
|
handler: async (args) => {
|
|
39
41
|
validateRequired(args, ["planet_id", "datetime"]);
|
|
40
42
|
const body = {
|
|
@@ -81,7 +83,8 @@ registerTool({
|
|
|
81
83
|
required: ["datetime", "latitude", "longitude"],
|
|
82
84
|
additionalProperties: false,
|
|
83
85
|
},
|
|
84
|
-
|
|
86
|
+
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
87
|
+
annotations: { title: "House Cusps", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
85
88
|
handler: async (args) => {
|
|
86
89
|
validateRequired(args, ["datetime", "latitude", "longitude"]);
|
|
87
90
|
const body = {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { registerTool, validateRequired } from "../index.js";
|
|
2
2
|
import { getActiveClient } from "../../backend/client.js";
|
|
3
|
+
import { OUTPUT_SCHEMA_JSON } from "../output-schemas.js";
|
|
3
4
|
function buildSubject(name, datetime, lat, lon) {
|
|
4
5
|
return {
|
|
5
6
|
name,
|
|
@@ -42,7 +43,8 @@ registerTool({
|
|
|
42
43
|
required: ["subjects"],
|
|
43
44
|
additionalProperties: false,
|
|
44
45
|
},
|
|
45
|
-
|
|
46
|
+
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
47
|
+
annotations: { title: "Natal Batch Charts", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
46
48
|
handler: async (args) => {
|
|
47
49
|
validateRequired(args, ["subjects"]);
|
|
48
50
|
const items = args.subjects.map((s) => ({
|
|
@@ -65,7 +67,8 @@ registerTool({
|
|
|
65
67
|
required: ["datetime"],
|
|
66
68
|
additionalProperties: false,
|
|
67
69
|
},
|
|
68
|
-
|
|
70
|
+
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
71
|
+
annotations: { title: "Essential Dignities", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
69
72
|
handler: async (args) => {
|
|
70
73
|
validateRequired(args, ["datetime"]);
|
|
71
74
|
return await getActiveClient().post("/ephemeris/dignities", {
|
|
@@ -92,7 +95,8 @@ registerTool({
|
|
|
92
95
|
required: ["datetime"],
|
|
93
96
|
additionalProperties: false,
|
|
94
97
|
},
|
|
95
|
-
|
|
98
|
+
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
99
|
+
annotations: { title: "Retrograde Status", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
96
100
|
handler: async (args) => {
|
|
97
101
|
validateRequired(args, ["datetime"]);
|
|
98
102
|
const client = getActiveClient();
|
|
@@ -141,7 +145,8 @@ registerTool({
|
|
|
141
145
|
required: ["datetime", "latitude", "longitude"],
|
|
142
146
|
additionalProperties: false,
|
|
143
147
|
},
|
|
144
|
-
|
|
148
|
+
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
149
|
+
annotations: { title: "Midpoints", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
145
150
|
handler: async (args) => {
|
|
146
151
|
validateRequired(args, ["datetime", "latitude", "longitude"]);
|
|
147
152
|
return await getActiveClient().post("/ephemeris/midpoints", {
|
|
@@ -171,7 +176,8 @@ registerTool({
|
|
|
171
176
|
required: ["datetime"],
|
|
172
177
|
additionalProperties: false,
|
|
173
178
|
},
|
|
174
|
-
|
|
179
|
+
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
180
|
+
annotations: { title: "Fixed Stars", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
175
181
|
handler: async (args) => {
|
|
176
182
|
validateRequired(args, ["datetime"]);
|
|
177
183
|
const body = {
|
|
@@ -231,7 +237,8 @@ registerTool({
|
|
|
231
237
|
required: ["datetime", "latitude", "longitude"],
|
|
232
238
|
additionalProperties: false,
|
|
233
239
|
},
|
|
234
|
-
|
|
240
|
+
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
241
|
+
annotations: { title: "Hermetic Lots", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
235
242
|
handler: async (args) => {
|
|
236
243
|
validateRequired(args, ["datetime", "latitude", "longitude"]);
|
|
237
244
|
return await getActiveClient().post("/ephemeris/hermetic-lots", {
|
|
@@ -257,7 +264,8 @@ registerTool({
|
|
|
257
264
|
required: ["datetime", "latitude", "longitude"],
|
|
258
265
|
additionalProperties: false,
|
|
259
266
|
},
|
|
260
|
-
|
|
267
|
+
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
268
|
+
annotations: { title: "Angles & Points", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
261
269
|
handler: async (args) => {
|
|
262
270
|
validateRequired(args, ["datetime", "latitude", "longitude"]);
|
|
263
271
|
return await getActiveClient().post("/ephemeris/angles-points", {
|
|
@@ -285,7 +293,8 @@ registerTool({
|
|
|
285
293
|
required: ["longitude_1", "longitude_2"],
|
|
286
294
|
additionalProperties: false,
|
|
287
295
|
},
|
|
288
|
-
|
|
296
|
+
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
297
|
+
annotations: { title: "Aspect Check", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
289
298
|
handler: async (args) => {
|
|
290
299
|
validateRequired(args, ["longitude_1", "longitude_2"]);
|
|
291
300
|
// Backend field names are longitude1 / longitude2 (no underscore)
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { registerTool, validateRequired } from "../index.js";
|
|
2
2
|
import { getActiveClient } from "../../backend/client.js";
|
|
3
|
+
import { OUTPUT_SCHEMA_JSON } from "../output-schemas.js";
|
|
3
4
|
/** Append 'Z' if no timezone offset is present in the datetime string. */
|
|
4
5
|
function ensureTimezone(dt) {
|
|
5
6
|
if (/[Zz]$/.test(dt) || /[+-]\d{2}:\d{2}$/.test(dt))
|
|
@@ -39,7 +40,8 @@ registerTool({
|
|
|
39
40
|
required: ["datetime"],
|
|
40
41
|
additionalProperties: false,
|
|
41
42
|
},
|
|
42
|
-
|
|
43
|
+
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
44
|
+
annotations: { title: "Human Design Bodygraph", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
43
45
|
handler: async (args) => {
|
|
44
46
|
validateRequired(args, ["datetime"]);
|
|
45
47
|
const body = {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { registerTool, validateRequired } from "../index.js";
|
|
2
2
|
import { getActiveClient } from "../../backend/client.js";
|
|
3
|
+
import { OUTPUT_SCHEMA_JSON } from "../output-schemas.js";
|
|
3
4
|
/**
|
|
4
5
|
* Ensure a datetime string has a timezone offset for Go's time.Time parsing.
|
|
5
6
|
*/
|
|
@@ -49,7 +50,8 @@ registerTool({
|
|
|
49
50
|
required: ["planet", "datetime", "return_year"],
|
|
50
51
|
additionalProperties: false,
|
|
51
52
|
},
|
|
52
|
-
|
|
53
|
+
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
54
|
+
annotations: { title: "HD Planetary Return", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
53
55
|
handler: async (args) => {
|
|
54
56
|
validateRequired(args, ["planet", "datetime", "return_year"]);
|
|
55
57
|
return await getActiveClient().request("POST", "/human-design/cycles/return", {
|
|
@@ -100,7 +102,8 @@ registerTool({
|
|
|
100
102
|
required: ["planet", "datetime", "target_year"],
|
|
101
103
|
additionalProperties: false,
|
|
102
104
|
},
|
|
103
|
-
|
|
105
|
+
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
106
|
+
annotations: { title: "HD Opposition Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
104
107
|
handler: async (args) => {
|
|
105
108
|
validateRequired(args, ["planet", "datetime", "target_year"]);
|
|
106
109
|
return await getActiveClient().request("POST", "/human-design/cycles/opposition", {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { registerTool, validateRequired } from "../index.js";
|
|
2
2
|
import { getActiveClient } from "../../backend/client.js";
|
|
3
|
+
import { OUTPUT_SCHEMA_JSON } from "../output-schemas.js";
|
|
3
4
|
// POST /human-design/composite — OE-027
|
|
4
5
|
registerTool({
|
|
5
6
|
name: "human_design_composite",
|
|
@@ -28,7 +29,8 @@ registerTool({
|
|
|
28
29
|
required: ["person_a_datetime", "person_b_datetime"],
|
|
29
30
|
additionalProperties: false,
|
|
30
31
|
},
|
|
31
|
-
|
|
32
|
+
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
33
|
+
annotations: { title: "HD Composite Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
32
34
|
handler: async (args) => {
|
|
33
35
|
validateRequired(args, ["person_a_datetime", "person_b_datetime"]);
|
|
34
36
|
const body = {
|
|
@@ -88,7 +90,8 @@ registerTool({
|
|
|
88
90
|
required: ["group_name", "members"],
|
|
89
91
|
additionalProperties: false,
|
|
90
92
|
},
|
|
91
|
-
|
|
93
|
+
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
94
|
+
annotations: { title: "HD Penta Group Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
92
95
|
handler: async (args) => {
|
|
93
96
|
validateRequired(args, ["group_name", "members"]);
|
|
94
97
|
const members = args.members.map((m) => ({
|
|
@@ -1,5 +1,6 @@
|
|
|
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
4
|
/**
|
|
4
5
|
* Ensure a datetime string has a timezone offset for Go's time.Time parsing.
|
|
5
6
|
* Go's encoding/json only accepts RFC 3339 (must have Z or +HH:MM offset).
|
|
@@ -64,7 +65,8 @@ registerTool({
|
|
|
64
65
|
required: ["datetime"],
|
|
65
66
|
additionalProperties: false,
|
|
66
67
|
},
|
|
67
|
-
|
|
68
|
+
outputSchema: OUTPUT_SCHEMA_IMAGE_AND_JSON,
|
|
69
|
+
annotations: { title: "Human Design Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
68
70
|
handler: async (args) => {
|
|
69
71
|
validateRequired(args, ["datetime"]);
|
|
70
72
|
const body = {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { registerTool, validateCoordinates } from "../index.js";
|
|
2
2
|
import { getActiveClient } from "../../backend/client.js";
|
|
3
|
+
import { OUTPUT_SCHEMA_JSON } from "../output-schemas.js";
|
|
3
4
|
registerTool({
|
|
4
5
|
name: "ephemeris_moon_phase",
|
|
5
6
|
description: "Get the Moon's current phase angle, illumination, and void-of-course status AT a specific " +
|
|
@@ -33,7 +34,8 @@ registerTool({
|
|
|
33
34
|
required: [],
|
|
34
35
|
additionalProperties: false,
|
|
35
36
|
},
|
|
36
|
-
|
|
37
|
+
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
38
|
+
annotations: { title: "Moon Phase", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
37
39
|
handler: async (args) => {
|
|
38
40
|
validateCoordinates(args, "latitude", "longitude");
|
|
39
41
|
const params = {};
|
|
@@ -91,7 +93,8 @@ registerTool({
|
|
|
91
93
|
required: ["phase"],
|
|
92
94
|
additionalProperties: false,
|
|
93
95
|
},
|
|
94
|
-
|
|
96
|
+
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
97
|
+
annotations: { title: "Next Lunar Phase", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
95
98
|
handler: async (args) => {
|
|
96
99
|
// Map our clean enum to display names the calendar API returns
|
|
97
100
|
const phaseNameMap = {
|
|
@@ -1,5 +1,6 @@
|
|
|
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
4
|
const DATETIME_DESC = "ISO 8601 datetime string, e.g. '1990-04-15T14:30:00' (local time at birth location). " +
|
|
4
5
|
"Include timezone offset if known, e.g. '1990-04-15T14:30:00-05:00'.";
|
|
5
6
|
/** Map human-readable house system names to standard single-letter codes */
|
|
@@ -73,7 +74,8 @@ registerTool({
|
|
|
73
74
|
required: ["datetime", "latitude", "longitude"],
|
|
74
75
|
additionalProperties: false,
|
|
75
76
|
},
|
|
76
|
-
|
|
77
|
+
outputSchema: OUTPUT_SCHEMA_IMAGE_AND_JSON,
|
|
78
|
+
annotations: { title: "Natal Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
77
79
|
handler: async (args) => {
|
|
78
80
|
validateRequired(args, ["datetime", "latitude", "longitude"]);
|
|
79
81
|
const body = {
|
|
@@ -1,5 +1,6 @@
|
|
|
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
4
|
registerTool({
|
|
4
5
|
name: "ephemeris_progressed_chart",
|
|
5
6
|
description: "Calculate a Secondary Progressed (or Solar Arc / Tertiary) chart. " +
|
|
@@ -56,7 +57,8 @@ registerTool({
|
|
|
56
57
|
required: ["birth_datetime", "birth_latitude", "birth_longitude", "target_datetime"],
|
|
57
58
|
additionalProperties: false,
|
|
58
59
|
},
|
|
59
|
-
|
|
60
|
+
outputSchema: OUTPUT_SCHEMA_IMAGE_AND_JSON,
|
|
61
|
+
annotations: { title: "Progressed Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
60
62
|
handler: async (args) => {
|
|
61
63
|
validateRequired(args, ["birth_datetime", "birth_latitude", "birth_longitude", "target_datetime"]);
|
|
62
64
|
const body = {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { registerTool, validateRequired } from "../index.js";
|
|
2
2
|
import { getActiveClient } from "../../backend/client.js";
|
|
3
|
+
import { OUTPUT_SCHEMA_JSON } from "../output-schemas.js";
|
|
3
4
|
registerTool({
|
|
4
5
|
name: "ephemeris_relocation",
|
|
5
6
|
description: "Calculate a relocation chart — the same natal planetary positions re-cast for a different " +
|
|
@@ -46,7 +47,8 @@ registerTool({
|
|
|
46
47
|
required: ["natal_datetime", "natal_latitude", "natal_longitude", "relocation_latitude", "relocation_longitude"],
|
|
47
48
|
additionalProperties: false,
|
|
48
49
|
},
|
|
49
|
-
|
|
50
|
+
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
51
|
+
annotations: { title: "Relocation Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
50
52
|
handler: async (args) => {
|
|
51
53
|
validateRequired(args, ["natal_datetime", "natal_latitude", "natal_longitude", "relocation_latitude", "relocation_longitude"]);
|
|
52
54
|
const body = {
|
|
@@ -1,5 +1,6 @@
|
|
|
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
4
|
// POST /predictive/returns/solar
|
|
4
5
|
registerTool({
|
|
5
6
|
name: "ephemeris_solar_return",
|
|
@@ -59,7 +60,8 @@ registerTool({
|
|
|
59
60
|
required: ["birth_datetime"],
|
|
60
61
|
additionalProperties: false,
|
|
61
62
|
},
|
|
62
|
-
|
|
63
|
+
outputSchema: OUTPUT_SCHEMA_IMAGE_AND_JSON,
|
|
64
|
+
annotations: { title: "Solar Return", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
63
65
|
handler: async (args) => {
|
|
64
66
|
validateRequired(args, ["birth_datetime"]);
|
|
65
67
|
// Default target to current year if not provided
|
|
@@ -127,7 +129,8 @@ registerTool({
|
|
|
127
129
|
required: ["birth_datetime"],
|
|
128
130
|
additionalProperties: false,
|
|
129
131
|
},
|
|
130
|
-
|
|
132
|
+
outputSchema: OUTPUT_SCHEMA_IMAGE_AND_JSON,
|
|
133
|
+
annotations: { title: "Lunar Return", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
131
134
|
handler: async (args) => {
|
|
132
135
|
validateRequired(args, ["birth_datetime"]);
|
|
133
136
|
const targetDt = args.target_datetime ?? new Date().toISOString();
|
|
@@ -182,7 +185,8 @@ registerTool({
|
|
|
182
185
|
required: ["body", "birth_datetime", "target_datetime"],
|
|
183
186
|
additionalProperties: false,
|
|
184
187
|
},
|
|
185
|
-
|
|
188
|
+
outputSchema: OUTPUT_SCHEMA_IMAGE_AND_JSON,
|
|
189
|
+
annotations: { title: "Planetary Return", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
186
190
|
handler: async (args) => {
|
|
187
191
|
validateRequired(args, ["body", "birth_datetime", "target_datetime"]);
|
|
188
192
|
const requestBody = {
|
|
@@ -1,5 +1,6 @@
|
|
|
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
4
|
registerTool({
|
|
4
5
|
name: "ephemeris_synastry",
|
|
5
6
|
description: "Calculate a synastry chart comparing two people's natal charts. Returns inter-aspects " +
|
|
@@ -50,7 +51,8 @@ registerTool({
|
|
|
50
51
|
],
|
|
51
52
|
additionalProperties: false,
|
|
52
53
|
},
|
|
53
|
-
|
|
54
|
+
outputSchema: OUTPUT_SCHEMA_IMAGE_AND_JSON,
|
|
55
|
+
annotations: { title: "Synastry Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
54
56
|
handler: async (args) => {
|
|
55
57
|
validateRequired(args, [
|
|
56
58
|
"person_a_datetime", "person_a_latitude", "person_a_longitude",
|
|
@@ -1,27 +1,22 @@
|
|
|
1
1
|
import { registerTool, validateRequired } from "../index.js";
|
|
2
2
|
import { getActiveClient } from "../../backend/client.js";
|
|
3
|
+
import { OUTPUT_SCHEMA_JSON } from "../output-schemas.js";
|
|
3
4
|
registerTool({
|
|
4
5
|
name: "ephemeris_transits",
|
|
5
6
|
description: "Search for astrological transit events affecting a natal chart over a date range. " +
|
|
6
|
-
"Returns
|
|
7
|
-
"to natal planet positions
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"ASPECT ANGLES: Use aspect_angle to search for specific aspects
|
|
7
|
+
"Returns exact transit moments — when transiting planets form specified aspects " +
|
|
8
|
+
"to natal planet positions.\n\n" +
|
|
9
|
+
"EFFICIENCY TIP: Always specify both transiting_planets and natal_points to keep " +
|
|
10
|
+
"compute fast. Omitting both sends all outer planets against all core natal positions " +
|
|
11
|
+
"— a much heavier computation.\n\n" +
|
|
12
|
+
"ASPECT ANGLES: Use aspect_angle to search for specific aspects:\n" +
|
|
12
13
|
" 0 = conjunction/return (default), 180 = opposition, 90 = square, 120 = trine.\n" +
|
|
13
14
|
" Example: Saturn Return → transiting_planets=['saturn'], natal_points=['saturn'], aspect_angle=0\n" +
|
|
14
15
|
" Example: Uranus Opposition → transiting_planets=['uranus'], natal_points=['uranus'], aspect_angle=180\n" +
|
|
15
|
-
" Example:
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"CREDIT COST: 6 credits per call
|
|
19
|
-
"Requests exceeding 30 seconds incur 1 additional credit per 30s of compute time.\n\n" +
|
|
20
|
-
"SEARCH RANGE LIMITS: Explorer tier is limited to 1-year windows; Developer to 5 years. " +
|
|
21
|
-
"Ranges exceeding the limit are silently clamped.\n\n" +
|
|
22
|
-
"EXAMPLE: Find all Saturn transits to the natal Sun/Moon for the next 6 months:\n" +
|
|
23
|
-
" natal_datetime='1990-04-15T14:30:00', natal_latitude=41.8781, natal_longitude=-87.6298,\n" +
|
|
24
|
-
" start_date='2026-01-01', end_date='2026-06-30', transiting_planets=['saturn']",
|
|
16
|
+
" Example: Outer planets to natal Sun/Moon → transiting_planets=['saturn','uranus','neptune','pluto'], natal_points=['sun','moon']\n\n" +
|
|
17
|
+
"DEFAULT natal_points (when omitted): sun, moon, mercury, venus, mars, jupiter, saturn.\n" +
|
|
18
|
+
"SEARCH RANGE LIMITS: Explorer/PayG tier → 1 year max; Developer → 5 years; Startup → 10 years.\n" +
|
|
19
|
+
"CREDIT COST: 6 credits per call.",
|
|
25
20
|
inputSchema: {
|
|
26
21
|
type: "object",
|
|
27
22
|
properties: {
|
|
@@ -66,7 +61,8 @@ registerTool({
|
|
|
66
61
|
required: ["natal_datetime", "natal_latitude", "natal_longitude", "start_date", "end_date"],
|
|
67
62
|
additionalProperties: false,
|
|
68
63
|
},
|
|
69
|
-
|
|
64
|
+
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
65
|
+
annotations: { title: "Transit Search", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
70
66
|
handler: async (args) => {
|
|
71
67
|
validateRequired(args, ["natal_datetime", "natal_latitude", "natal_longitude", "start_date", "end_date"]);
|
|
72
68
|
// ── Step 1: Compute natal chart to extract real planetary longitudes ──
|
|
@@ -87,35 +83,49 @@ registerTool({
|
|
|
87
83
|
// The natal response typically has a `planets` array or object
|
|
88
84
|
const planets = natalResult?.planets || natalResult?.data?.planets || [];
|
|
89
85
|
const planetArray = Array.isArray(planets) ? planets : Object.values(planets);
|
|
90
|
-
//
|
|
86
|
+
// ── Core bodies used when no natal_points filter is given ────────────
|
|
87
|
+
// Defaulting to all planets creates 40+ serial SearchTransit calls on the
|
|
88
|
+
// backend (10+ targets × 4+ outer planets). Cap to the 7 classical bodies.
|
|
89
|
+
const CORE_BODIES_DEFAULT = new Set([
|
|
90
|
+
"sun", "moon", "mercury", "venus", "mars", "jupiter", "saturn",
|
|
91
|
+
]);
|
|
91
92
|
const wantedPoints = args.natal_points
|
|
92
93
|
? new Set(args.natal_points.map((p) => p.toLowerCase()))
|
|
93
|
-
:
|
|
94
|
+
: CORE_BODIES_DEFAULT;
|
|
94
95
|
for (const planet of planetArray) {
|
|
95
96
|
const name = (planet.name || planet.id || "").toLowerCase();
|
|
96
97
|
const lon = planet.longitude ?? planet.ecliptic_longitude ?? planet.lon;
|
|
97
98
|
if (typeof lon !== "number" || !isFinite(lon))
|
|
98
99
|
continue;
|
|
99
|
-
if (
|
|
100
|
+
if (!wantedPoints.has(name))
|
|
100
101
|
continue;
|
|
101
|
-
targetDegrees.push(Math.round(lon * 100) / 100);
|
|
102
|
+
targetDegrees.push(Math.round(lon * 100) / 100);
|
|
102
103
|
natalPositionMap[name] = lon;
|
|
103
104
|
}
|
|
104
|
-
//
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
105
|
+
// Extract angles (ASC, MC) only when explicitly requested
|
|
106
|
+
if (args.natal_points) {
|
|
107
|
+
const angles = natalResult?.angles || natalResult?.data?.angles;
|
|
108
|
+
if (angles) {
|
|
109
|
+
const angleEntries = Array.isArray(angles)
|
|
110
|
+
? angles
|
|
111
|
+
: Object.entries(angles).map(([k, v]) => ({ name: k, ...(typeof v === "object" ? v : { longitude: v }) }));
|
|
112
|
+
for (const angle of angleEntries) {
|
|
113
|
+
const name = (angle.name || angle.id || "").toLowerCase();
|
|
114
|
+
const lon = angle.longitude ?? angle.ecliptic_longitude ?? angle.lon;
|
|
115
|
+
if (typeof lon !== "number" || !isFinite(lon))
|
|
116
|
+
continue;
|
|
117
|
+
if (!wantedPoints.has(name))
|
|
118
|
+
continue;
|
|
119
|
+
targetDegrees.push(Math.round(lon * 100) / 100);
|
|
120
|
+
natalPositionMap[name] = lon;
|
|
121
|
+
}
|
|
117
122
|
}
|
|
118
123
|
}
|
|
124
|
+
// Hard cap: never send more than 12 target degrees
|
|
125
|
+
const MAX_TARGETS = 12;
|
|
126
|
+
if (targetDegrees.length > MAX_TARGETS) {
|
|
127
|
+
targetDegrees.splice(MAX_TARGETS);
|
|
128
|
+
}
|
|
119
129
|
if (targetDegrees.length === 0) {
|
|
120
130
|
throw new Error("Could not extract natal planet longitudes from the natal chart calculation. " +
|
|
121
131
|
"Please verify your natal_datetime, natal_latitude, and natal_longitude are correct.");
|
|
@@ -129,23 +139,22 @@ registerTool({
|
|
|
129
139
|
if (/^\d{4}-\d{2}-\d{2}$/.test(endStr)) {
|
|
130
140
|
endStr += "T23:59:59Z";
|
|
131
141
|
}
|
|
142
|
+
const aspectAngle = typeof args.aspect_angle === "number" ? args.aspect_angle : 0;
|
|
143
|
+
let effectiveTargets = targetDegrees;
|
|
144
|
+
if (aspectAngle !== 0) {
|
|
145
|
+
effectiveTargets = targetDegrees.map((deg) => ((deg + aspectAngle) % 360 + 360) % 360);
|
|
146
|
+
}
|
|
132
147
|
const transitBody = {
|
|
133
148
|
start_date: startStr,
|
|
134
149
|
end_date: endStr,
|
|
135
|
-
target_degrees:
|
|
150
|
+
target_degrees: effectiveTargets,
|
|
136
151
|
};
|
|
137
152
|
if (args.transiting_planets)
|
|
138
153
|
transitBody.planet_names = args.transiting_planets;
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
let effectiveTargets = targetDegrees;
|
|
142
|
-
if (typeof args.aspect_angle === "number" && args.aspect_angle !== 0) {
|
|
143
|
-
effectiveTargets = targetDegrees.map((deg) => ((deg + args.aspect_angle) % 360 + 360) % 360);
|
|
144
|
-
transitBody.target_degrees = effectiveTargets;
|
|
145
|
-
// Also include aspect metadata for labeling in results
|
|
146
|
-
transitBody.search_criteria = { aspect_angle: args.aspect_angle };
|
|
154
|
+
if (aspectAngle !== 0) {
|
|
155
|
+
transitBody.search_criteria = { aspect_angle: aspectAngle };
|
|
147
156
|
}
|
|
148
|
-
const transitResult = await getActiveClient().request("POST", "/predictive/transits/search", { data: transitBody });
|
|
157
|
+
const transitResult = await getActiveClient().request("POST", "/predictive/transits/search", { data: transitBody, timeoutMs: 90_000 });
|
|
149
158
|
// Return combined context so the LLM knows what natal positions were targeted
|
|
150
159
|
return {
|
|
151
160
|
natal_positions: natalPositionMap,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { registerTool, validateRequired, validateCoordinates } from "../index.js";
|
|
2
2
|
import { getActiveClient } from "../../backend/client.js";
|
|
3
|
+
import { OUTPUT_SCHEMA_JSON } from "../output-schemas.js";
|
|
3
4
|
registerTool({
|
|
4
5
|
name: "vedic_chart",
|
|
5
6
|
description: "Calculate a Vedic (Jyotish) natal chart with sidereal positions. Returns planet placements " +
|
|
@@ -33,7 +34,8 @@ registerTool({
|
|
|
33
34
|
required: ["datetime", "latitude", "longitude"],
|
|
34
35
|
additionalProperties: false,
|
|
35
36
|
},
|
|
36
|
-
|
|
37
|
+
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
38
|
+
annotations: { title: "Vedic Natal Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
37
39
|
handler: async (args) => {
|
|
38
40
|
validateRequired(args, ["datetime", "latitude", "longitude"]);
|
|
39
41
|
validateCoordinates(args, "latitude", "longitude");
|