@openephemeris/mcp-server 4.8.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.
- package/CHANGELOG.md +12 -0
- package/dist/tools/apps/bazi-app.js +1 -1
- package/dist/tools/apps/bi-wheel-app.js +5 -5
- package/dist/tools/apps/bodygraph-app.js +8 -8
- package/dist/tools/apps/chart-wheel-app.js +4 -4
- package/dist/tools/apps/location-tools.js +2 -2
- package/dist/tools/apps/moon-phase-app.js +1 -1
- package/dist/tools/apps/vedic-chart-app.js +1 -1
- package/dist/tools/auth.js +8 -0
- package/dist/tools/dev.js +15 -5
- package/dist/tools/specialized/account.js +5 -1
- package/dist/tools/specialized/acg.js +2 -2
- package/dist/tools/specialized/bazi.js +7 -7
- package/dist/tools/specialized/bi_wheel.js +1 -1
- package/dist/tools/specialized/chart_wheel.js +1 -1
- package/dist/tools/specialized/comparative.js +4 -4
- package/dist/tools/specialized/eclipse.js +1 -1
- package/dist/tools/specialized/electional.js +5 -5
- package/dist/tools/specialized/ephemeris_core.js +2 -2
- package/dist/tools/specialized/ephemeris_extended.js +8 -8
- package/dist/tools/specialized/hd_bodygraph.js +1 -1
- package/dist/tools/specialized/hd_cycles.js +2 -2
- package/dist/tools/specialized/hd_group.js +2 -2
- package/dist/tools/specialized/human_design.js +1 -1
- package/dist/tools/specialized/moon.js +2 -2
- package/dist/tools/specialized/natal.js +1 -1
- package/dist/tools/specialized/progressed.js +1 -1
- package/dist/tools/specialized/relocation.js +1 -1
- package/dist/tools/specialized/returns.js +3 -3
- package/dist/tools/specialized/synastry.js +1 -1
- package/dist/tools/specialized/transits.js +1 -1
- package/dist/tools/specialized/vedic.js +1 -1
- package/dist/tools/specialized/venus_star_points.js +6 -6
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,18 @@ Version numbering follows [Semantic Versioning](https://semver.org/).
|
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
+
## [4.8.1] — 2026-08-02
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- Every tool now declares all four MCP annotation hints explicitly
|
|
14
|
+
(`readOnlyHint`, `destructiveHint`, `idempotentHint`, `openWorldHint`).
|
|
15
|
+
Notably `dev_write_api` is `destructiveHint: false` — every allowlisted
|
|
16
|
+
write is stateless chart computation — so strict clients no longer gate it
|
|
17
|
+
behind a confirmation, and `openWorldHint` is uniformly `false` (the server
|
|
18
|
+
reaches only the fixed OpenEphemeris API).
|
|
19
|
+
- `account_usage` reports a real authentication failure as a tool error
|
|
20
|
+
(`isError: true`) instead of a success-shaped message.
|
|
21
|
+
|
|
10
22
|
## [4.8.0] — 2026-08-02
|
|
11
23
|
|
|
12
24
|
### Added
|
|
@@ -204,7 +204,7 @@ registerTool({
|
|
|
204
204
|
required: ["year", "month", "day"],
|
|
205
205
|
},
|
|
206
206
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
207
|
-
annotations: { title: "Recalculate BaZi Chart", readOnlyHint: true, openWorldHint: false },
|
|
207
|
+
annotations: { title: "Recalculate BaZi Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
208
208
|
_meta: { ui: { resourceUri: BAZI_RESOURCE_URI, visibility: ["app"] } },
|
|
209
209
|
handler: async (args) => {
|
|
210
210
|
const components = parseBaziArgs(args);
|
|
@@ -588,7 +588,7 @@ registerTool({
|
|
|
588
588
|
required: ["mode", "person1_datetime", "person1_latitude", "person1_longitude", "person2_datetime"],
|
|
589
589
|
},
|
|
590
590
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
591
|
-
annotations: { title: "Recalculate Bi-Wheel", readOnlyHint: true, openWorldHint: false },
|
|
591
|
+
annotations: { title: "Recalculate Bi-Wheel", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
592
592
|
_meta: { ui: { resourceUri: BI_WHEEL_RESOURCE_URI, visibility: ["app"] } },
|
|
593
593
|
handler: async (args) => {
|
|
594
594
|
const client = getActiveClient();
|
|
@@ -644,7 +644,7 @@ registerTool({
|
|
|
644
644
|
required: ["planet1", "planet2", "aspect_type"],
|
|
645
645
|
},
|
|
646
646
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
647
|
-
annotations: { title: "Cross-Aspect Interpretation", readOnlyHint: true, openWorldHint: false },
|
|
647
|
+
annotations: { title: "Cross-Aspect Interpretation", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
648
648
|
_meta: { ui: { resourceUri: BI_WHEEL_RESOURCE_URI, visibility: ["app"] } },
|
|
649
649
|
handler: async (args) => {
|
|
650
650
|
const p1 = capitalize(String(args.planet1));
|
|
@@ -683,7 +683,7 @@ registerTool({
|
|
|
683
683
|
required: ["planet", "wheel", "longitude"],
|
|
684
684
|
},
|
|
685
685
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
686
|
-
annotations: { title: "Bi-Wheel Planet Interpretation", readOnlyHint: true, openWorldHint: false },
|
|
686
|
+
annotations: { title: "Bi-Wheel Planet Interpretation", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
687
687
|
_meta: { ui: { resourceUri: BI_WHEEL_RESOURCE_URI, visibility: ["app"] } },
|
|
688
688
|
handler: async (args) => {
|
|
689
689
|
const planet = String(args.planet);
|
|
@@ -884,7 +884,7 @@ registerTool({
|
|
|
884
884
|
required: ["house_number"],
|
|
885
885
|
},
|
|
886
886
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
887
|
-
annotations: { title: "Bi-Wheel House Interpretation", readOnlyHint: true, openWorldHint: false },
|
|
887
|
+
annotations: { title: "Bi-Wheel House Interpretation", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
888
888
|
_meta: { ui: { resourceUri: BI_WHEEL_RESOURCE_URI, visibility: ["app"] } },
|
|
889
889
|
handler: async (args) => {
|
|
890
890
|
const num = Number(args.house_number);
|
|
@@ -944,7 +944,7 @@ registerTool({
|
|
|
944
944
|
required: ["mode"],
|
|
945
945
|
},
|
|
946
946
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
947
|
-
annotations: { title: "Bi-Wheel Synopsis", readOnlyHint: true, openWorldHint: false },
|
|
947
|
+
annotations: { title: "Bi-Wheel Synopsis", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
948
948
|
_meta: { ui: { resourceUri: BI_WHEEL_RESOURCE_URI, visibility: ["app", "model"] } },
|
|
949
949
|
handler: async (args) => {
|
|
950
950
|
const mode = args.mode ?? "synastry";
|
|
@@ -471,7 +471,7 @@ registerTool({
|
|
|
471
471
|
required: ["datetime"],
|
|
472
472
|
},
|
|
473
473
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
474
|
-
annotations: { title: "Recalculate Bodygraph", readOnlyHint: true, openWorldHint: false },
|
|
474
|
+
annotations: { title: "Recalculate Bodygraph", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
475
475
|
_meta: { ui: { resourceUri: BODYGRAPH_RESOURCE_URI, visibility: ["app"] } },
|
|
476
476
|
handler: async (args) => {
|
|
477
477
|
const client = getActiveClient();
|
|
@@ -536,7 +536,7 @@ registerTool({
|
|
|
536
536
|
required: ["center", "defined"],
|
|
537
537
|
},
|
|
538
538
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
539
|
-
annotations: { title: "Center Interpretation", readOnlyHint: true, openWorldHint: false },
|
|
539
|
+
annotations: { title: "Center Interpretation", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
540
540
|
_meta: { ui: { resourceUri: BODYGRAPH_RESOURCE_URI, visibility: ["app"] } },
|
|
541
541
|
handler: async (args) => {
|
|
542
542
|
const center = String(args.center);
|
|
@@ -594,7 +594,7 @@ registerTool({
|
|
|
594
594
|
required: ["gate"],
|
|
595
595
|
},
|
|
596
596
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
597
|
-
annotations: { title: "Gate Interpretation", readOnlyHint: true, openWorldHint: false },
|
|
597
|
+
annotations: { title: "Gate Interpretation", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
598
598
|
_meta: { ui: { resourceUri: BODYGRAPH_RESOURCE_URI, visibility: ["app"] } },
|
|
599
599
|
handler: async (args) => {
|
|
600
600
|
const gate = Number(args.gate);
|
|
@@ -649,7 +649,7 @@ registerTool({
|
|
|
649
649
|
required: ["channel"],
|
|
650
650
|
},
|
|
651
651
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
652
|
-
annotations: { title: "Channel Interpretation", readOnlyHint: true, openWorldHint: false },
|
|
652
|
+
annotations: { title: "Channel Interpretation", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
653
653
|
_meta: { ui: { resourceUri: BODYGRAPH_RESOURCE_URI, visibility: ["app"] } },
|
|
654
654
|
handler: async (args) => {
|
|
655
655
|
const channelStr = String(args.channel);
|
|
@@ -751,7 +751,7 @@ registerTool({
|
|
|
751
751
|
required: ["channel"],
|
|
752
752
|
},
|
|
753
753
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
754
|
-
annotations: { title: "Connection Channel Interpretation", readOnlyHint: true, openWorldHint: false },
|
|
754
|
+
annotations: { title: "Connection Channel Interpretation", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
755
755
|
_meta: { ui: { resourceUri: BODYGRAPH_RESOURCE_URI, visibility: ["app"] } },
|
|
756
756
|
handler: async (args) => {
|
|
757
757
|
const channelStr = String(args.channel ?? "");
|
|
@@ -807,7 +807,7 @@ registerTool({
|
|
|
807
807
|
required: ["channel"],
|
|
808
808
|
},
|
|
809
809
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
810
|
-
annotations: { title: "Transit Channel Interpretation", readOnlyHint: true, openWorldHint: false },
|
|
810
|
+
annotations: { title: "Transit Channel Interpretation", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
811
811
|
_meta: { ui: { resourceUri: BODYGRAPH_RESOURCE_URI, visibility: ["app"] } },
|
|
812
812
|
handler: async (args) => {
|
|
813
813
|
const channelStr = String(args.channel ?? "");
|
|
@@ -1135,7 +1135,7 @@ registerTool({
|
|
|
1135
1135
|
required: ["planet", "column"],
|
|
1136
1136
|
},
|
|
1137
1137
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
1138
|
-
annotations: { title: "Planet Sidebar Interpretation", readOnlyHint: true, openWorldHint: false },
|
|
1138
|
+
annotations: { title: "Planet Sidebar Interpretation", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
1139
1139
|
_meta: { ui: { resourceUri: BODYGRAPH_RESOURCE_URI, visibility: ["app"] } },
|
|
1140
1140
|
handler: async (args) => {
|
|
1141
1141
|
const planet = String(args.planet);
|
|
@@ -1204,7 +1204,7 @@ registerTool({
|
|
|
1204
1204
|
required: ["variable", "direction"],
|
|
1205
1205
|
},
|
|
1206
1206
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
1207
|
-
annotations: { title: "Variable Arrow Interpretation", readOnlyHint: true, openWorldHint: false },
|
|
1207
|
+
annotations: { title: "Variable Arrow Interpretation", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
1208
1208
|
_meta: { ui: { resourceUri: BODYGRAPH_RESOURCE_URI, visibility: ["app"] } },
|
|
1209
1209
|
handler: async (args) => {
|
|
1210
1210
|
const variable = String(args.variable).toLowerCase();
|
|
@@ -259,7 +259,7 @@ registerTool({
|
|
|
259
259
|
required: ["planet", "longitude"],
|
|
260
260
|
},
|
|
261
261
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
262
|
-
annotations: { title: "Planet Interpretation", readOnlyHint: true, openWorldHint: false },
|
|
262
|
+
annotations: { title: "Planet Interpretation", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
263
263
|
_meta: { ui: { resourceUri: CHART_WHEEL_RESOURCE_URI, visibility: ["app"] } },
|
|
264
264
|
handler: async (args) => {
|
|
265
265
|
const planet = String(args.planet);
|
|
@@ -294,7 +294,7 @@ registerTool({
|
|
|
294
294
|
required: ["house_number"],
|
|
295
295
|
},
|
|
296
296
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
297
|
-
annotations: { title: "House Interpretation", readOnlyHint: true, openWorldHint: false },
|
|
297
|
+
annotations: { title: "House Interpretation", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
298
298
|
_meta: { ui: { resourceUri: CHART_WHEEL_RESOURCE_URI, visibility: ["app"] } },
|
|
299
299
|
handler: async (args) => {
|
|
300
300
|
const num = Number(args.house_number);
|
|
@@ -330,7 +330,7 @@ registerTool({
|
|
|
330
330
|
required: ["planet1", "planet2"],
|
|
331
331
|
},
|
|
332
332
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
333
|
-
annotations: { title: "Aspect Interpretation", readOnlyHint: true, openWorldHint: false },
|
|
333
|
+
annotations: { title: "Aspect Interpretation", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
334
334
|
_meta: { ui: { resourceUri: CHART_WHEEL_RESOURCE_URI, visibility: ["app"] } },
|
|
335
335
|
handler: async (args) => {
|
|
336
336
|
const p1 = capitalize(String(args.planet1));
|
|
@@ -379,7 +379,7 @@ registerTool({
|
|
|
379
379
|
required: ["datetime", "latitude", "longitude", "house_system"],
|
|
380
380
|
},
|
|
381
381
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
382
|
-
annotations: { title: "Recalculate Chart", readOnlyHint: true, openWorldHint: false },
|
|
382
|
+
annotations: { title: "Recalculate Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
383
383
|
_meta: { ui: { resourceUri: CHART_WHEEL_RESOURCE_URI, visibility: ["app"] } },
|
|
384
384
|
handler: async (args) => {
|
|
385
385
|
const client = getActiveClient();
|
|
@@ -131,7 +131,7 @@ registerTool({
|
|
|
131
131
|
additionalProperties: false,
|
|
132
132
|
},
|
|
133
133
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
134
|
-
annotations: { title: "Location Search", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
134
|
+
annotations: { title: "Location Search", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
135
135
|
// Model-visible as well as app-visible: without this the model had no
|
|
136
136
|
// geocoding tool and every prompt had to route through
|
|
137
137
|
// `dev_read_api /location/autocomplete` instead.
|
|
@@ -235,7 +235,7 @@ registerTool({
|
|
|
235
235
|
additionalProperties: false,
|
|
236
236
|
},
|
|
237
237
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
238
|
-
annotations: { title: "Timezone Resolve", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
238
|
+
annotations: { title: "Timezone Resolve", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
239
239
|
_meta: {
|
|
240
240
|
ui: {
|
|
241
241
|
visibility: ["model", "app"],
|
|
@@ -295,7 +295,7 @@ registerTool({
|
|
|
295
295
|
additionalProperties: false,
|
|
296
296
|
},
|
|
297
297
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
298
|
-
annotations: { title: "Recalculate Moon Phase", readOnlyHint: true, openWorldHint: false },
|
|
298
|
+
annotations: { title: "Recalculate Moon Phase", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
299
299
|
_meta: { ui: { resourceUri: MOON_PHASE_RESOURCE_URI, visibility: ["app"] } },
|
|
300
300
|
handler: async (args) => {
|
|
301
301
|
const { summary, uiPayload } = await computeMoonData(args);
|
|
@@ -240,7 +240,7 @@ registerTool({
|
|
|
240
240
|
required: ["datetime"],
|
|
241
241
|
},
|
|
242
242
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
243
|
-
annotations: { title: "Recalculate Vedic Chart", readOnlyHint: true, openWorldHint: false },
|
|
243
|
+
annotations: { title: "Recalculate Vedic Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
244
244
|
_meta: { ui: { resourceUri: VEDIC_CHART_RESOURCE_URI, visibility: ["app"] } },
|
|
245
245
|
handler: async (args) => {
|
|
246
246
|
const client = getActiveClient();
|
package/dist/tools/auth.js
CHANGED
|
@@ -24,6 +24,10 @@ registerTool({
|
|
|
24
24
|
title: "Connect Account",
|
|
25
25
|
readOnlyHint: false,
|
|
26
26
|
destructiveHint: false,
|
|
27
|
+
// Each call starts a fresh device-auth flow with a new code — repeating
|
|
28
|
+
// it is harmless but not a no-op.
|
|
29
|
+
idempotentHint: false,
|
|
30
|
+
openWorldHint: false,
|
|
27
31
|
},
|
|
28
32
|
stdioOnly: true,
|
|
29
33
|
handler: async () => {
|
|
@@ -105,6 +109,8 @@ registerTool({
|
|
|
105
109
|
title: "Auth Status",
|
|
106
110
|
readOnlyHint: true,
|
|
107
111
|
destructiveHint: false,
|
|
112
|
+
idempotentHint: true,
|
|
113
|
+
openWorldHint: false,
|
|
108
114
|
},
|
|
109
115
|
stdioOnly: true,
|
|
110
116
|
handler: async () => {
|
|
@@ -191,6 +197,8 @@ registerTool({
|
|
|
191
197
|
title: "Disconnect Account",
|
|
192
198
|
readOnlyHint: false,
|
|
193
199
|
destructiveHint: true,
|
|
200
|
+
idempotentHint: true,
|
|
201
|
+
openWorldHint: false,
|
|
194
202
|
},
|
|
195
203
|
stdioOnly: true,
|
|
196
204
|
handler: async () => {
|
package/dist/tools/dev.js
CHANGED
|
@@ -196,8 +196,10 @@ registerTool({
|
|
|
196
196
|
DEV_API_REFERENCE,
|
|
197
197
|
inputSchema: makeProxyInputSchema(READ_METHODS),
|
|
198
198
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
199
|
-
// GET-only: never mutates server state.
|
|
200
|
-
|
|
199
|
+
// GET-only: never mutates server state. openWorldHint false — the proxy
|
|
200
|
+
// reaches only the fixed, allowlisted OpenEphemeris API (a closed world),
|
|
201
|
+
// same as every typed tool.
|
|
202
|
+
annotations: { title: "API Read", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
201
203
|
handler: makeProxyHandler(READ_METHODS, "GET"),
|
|
202
204
|
});
|
|
203
205
|
registerTool({
|
|
@@ -209,8 +211,16 @@ registerTool({
|
|
|
209
211
|
DEV_API_REFERENCE,
|
|
210
212
|
inputSchema: makeProxyInputSchema(WRITE_METHODS),
|
|
211
213
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
212
|
-
// Issues POST/PUT/PATCH/DELETE — must not be advertised as read-only.
|
|
213
|
-
|
|
214
|
+
// Issues POST/PUT/PATCH/DELETE — must not be advertised as read-only. But
|
|
215
|
+
// destructiveHint is explicitly FALSE: every allowlisted write operation is
|
|
216
|
+
// stateless chart computation (natal, synastry, ACG, returns…) that debits
|
|
217
|
+
// credits and returns a result — nothing on the allowlist mutates or deletes
|
|
218
|
+
// user data, and the deny rules block /auth, /billing, /account, /api-keys.
|
|
219
|
+
// Left unset, strict clients default destructiveHint to true and gate every
|
|
220
|
+
// call behind a confirmation. idempotentHint true for the same reason: the
|
|
221
|
+
// same body yields the same chart. openWorldHint false — fixed allowlisted
|
|
222
|
+
// API only, a closed world.
|
|
223
|
+
annotations: { title: "API Write", readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
214
224
|
handler: makeProxyHandler(WRITE_METHODS, "POST"),
|
|
215
225
|
});
|
|
216
226
|
registerTool({
|
|
@@ -226,7 +236,7 @@ registerTool({
|
|
|
226
236
|
additionalProperties: false,
|
|
227
237
|
},
|
|
228
238
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
229
|
-
annotations: { title: "List Allowed API Operations", readOnlyHint: true, openWorldHint: false },
|
|
239
|
+
annotations: { title: "List Allowed API Operations", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
230
240
|
handler: async () => {
|
|
231
241
|
const allowlist = loadAllowlist();
|
|
232
242
|
return {
|
|
@@ -27,7 +27,7 @@ registerTool({
|
|
|
27
27
|
additionalProperties: false,
|
|
28
28
|
},
|
|
29
29
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
30
|
-
annotations: { title: "Account Usage", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
30
|
+
annotations: { title: "Account Usage", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
31
31
|
handler: async (args) => {
|
|
32
32
|
const params = {};
|
|
33
33
|
if (args?.month)
|
|
@@ -39,7 +39,11 @@ registerTool({
|
|
|
39
39
|
}
|
|
40
40
|
catch (error) {
|
|
41
41
|
if (error instanceof BackendError && error.status === 401) {
|
|
42
|
+
// A real auth failure must carry isError — a success-shaped response
|
|
43
|
+
// teaches the model the call worked and it stops trying to fix auth.
|
|
44
|
+
// The guidance text is kept so hosts still show the user a way forward.
|
|
42
45
|
return {
|
|
46
|
+
isError: true,
|
|
43
47
|
content: [{
|
|
44
48
|
type: "text",
|
|
45
49
|
text: `**Not signed in.** To check usage, connect an OpenEphemeris account first.\n\n` +
|
|
@@ -60,7 +60,7 @@ registerTool({
|
|
|
60
60
|
additionalProperties: false,
|
|
61
61
|
},
|
|
62
62
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
63
|
-
annotations: { title: "Astrocartography Lines", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
63
|
+
annotations: { title: "Astrocartography Lines", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
64
64
|
handler: async (args) => {
|
|
65
65
|
validateRequired(args, ["birth_datetime", "birth_latitude", "birth_longitude"]);
|
|
66
66
|
const body = {
|
|
@@ -157,7 +157,7 @@ registerTool({
|
|
|
157
157
|
additionalProperties: false,
|
|
158
158
|
},
|
|
159
159
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
160
|
-
annotations: { title: "Astrocartography Location Hits", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
160
|
+
annotations: { title: "Astrocartography Location Hits", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
161
161
|
handler: async (args) => {
|
|
162
162
|
validateRequired(args, ["birth_datetime", "birth_latitude", "birth_longitude", "query_latitude", "query_longitude"]);
|
|
163
163
|
const body = {
|
|
@@ -158,7 +158,7 @@ registerTool({
|
|
|
158
158
|
additionalProperties: false,
|
|
159
159
|
},
|
|
160
160
|
outputSchema: OUTPUT_SCHEMA_IMAGE_AND_JSON,
|
|
161
|
-
annotations: { title: "BaZi Four Pillars Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
161
|
+
annotations: { title: "BaZi Four Pillars Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
162
162
|
handler: async (args) => {
|
|
163
163
|
const body = { ...parseBaziArgs(args) };
|
|
164
164
|
applyVisualConfig(body, args);
|
|
@@ -195,7 +195,7 @@ registerTool({
|
|
|
195
195
|
additionalProperties: false,
|
|
196
196
|
},
|
|
197
197
|
outputSchema: OUTPUT_SCHEMA_IMAGE_AND_JSON,
|
|
198
|
-
annotations: { title: "BaZi Ten Gods", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
198
|
+
annotations: { title: "BaZi Ten Gods", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
199
199
|
handler: async (args) => {
|
|
200
200
|
const body = { ...parseBaziArgs(args) };
|
|
201
201
|
applyVisualConfig(body, args);
|
|
@@ -230,7 +230,7 @@ registerTool({
|
|
|
230
230
|
additionalProperties: false,
|
|
231
231
|
},
|
|
232
232
|
outputSchema: OUTPUT_SCHEMA_IMAGE_AND_JSON,
|
|
233
|
-
annotations: { title: "BaZi Element Balance", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
233
|
+
annotations: { title: "BaZi Element Balance", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
234
234
|
handler: async (args) => {
|
|
235
235
|
const body = { ...parseBaziArgs(args) };
|
|
236
236
|
applyVisualConfig(body, args);
|
|
@@ -273,7 +273,7 @@ registerTool({
|
|
|
273
273
|
additionalProperties: false,
|
|
274
274
|
},
|
|
275
275
|
outputSchema: OUTPUT_SCHEMA_IMAGE_AND_JSON,
|
|
276
|
-
annotations: { title: "BaZi Luck Pillars", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
276
|
+
annotations: { title: "BaZi Luck Pillars", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
277
277
|
handler: async (args) => {
|
|
278
278
|
if (!args.gender) {
|
|
279
279
|
throw new Error("gender is required for luck pillar calculation. " +
|
|
@@ -316,7 +316,7 @@ registerTool({
|
|
|
316
316
|
additionalProperties: false,
|
|
317
317
|
},
|
|
318
318
|
outputSchema: OUTPUT_SCHEMA_IMAGE_AND_JSON,
|
|
319
|
-
annotations: { title: "BaZi Annual Pillar", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
319
|
+
annotations: { title: "BaZi Annual Pillar", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
320
320
|
handler: async (args) => {
|
|
321
321
|
if (!args.year) {
|
|
322
322
|
throw new Error("year is required. Provide a Gregorian year (1–9999), e.g. year=2025.");
|
|
@@ -385,7 +385,7 @@ registerTool({
|
|
|
385
385
|
additionalProperties: false,
|
|
386
386
|
},
|
|
387
387
|
outputSchema: OUTPUT_SCHEMA_IMAGE_AND_JSON,
|
|
388
|
-
annotations: { title: "BaZi Compatibility", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
388
|
+
annotations: { title: "BaZi Compatibility", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
389
389
|
handler: async (args) => {
|
|
390
390
|
const chartAComponents = parseBaziArgs({
|
|
391
391
|
year: args.chart_a_year,
|
|
@@ -447,7 +447,7 @@ registerTool({
|
|
|
447
447
|
additionalProperties: false,
|
|
448
448
|
},
|
|
449
449
|
outputSchema: OUTPUT_SCHEMA_IMAGE_AND_JSON,
|
|
450
|
-
annotations: { title: "BaZi Chart (Visual)", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
450
|
+
annotations: { title: "BaZi Chart (Visual)", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
451
451
|
handler: async (args) => {
|
|
452
452
|
const { year, month, day, hour } = parseBaziArgs(args);
|
|
453
453
|
const body = {
|
|
@@ -40,7 +40,7 @@ registerTool({
|
|
|
40
40
|
additionalProperties: false,
|
|
41
41
|
},
|
|
42
42
|
outputSchema: OUTPUT_SCHEMA_IMAGE,
|
|
43
|
-
annotations: { title: "Bi-Wheel Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
43
|
+
annotations: { title: "Bi-Wheel Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
44
44
|
handler: async (args) => {
|
|
45
45
|
validateRequired(args, ["datetime_a", "latitude_a", "longitude_a", "datetime_b", "latitude_b", "longitude_b"]);
|
|
46
46
|
assertZonedDatetime("datetime_a", args.datetime_a, args.timezone_a, "timezone_a");
|
|
@@ -45,7 +45,7 @@ registerTool({
|
|
|
45
45
|
additionalProperties: false,
|
|
46
46
|
},
|
|
47
47
|
outputSchema: OUTPUT_SCHEMA_IMAGE,
|
|
48
|
-
annotations: { title: "Chart Wheel SVG", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
48
|
+
annotations: { title: "Chart Wheel SVG", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
49
49
|
handler: async (args) => {
|
|
50
50
|
validateRequired(args, ["datetime", "latitude", "longitude"]);
|
|
51
51
|
assertZonedDatetime("datetime", args.datetime, args.timezone);
|
|
@@ -51,7 +51,7 @@ registerTool({
|
|
|
51
51
|
additionalProperties: false,
|
|
52
52
|
},
|
|
53
53
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
54
|
-
annotations: { title: "Davison Relationship Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
54
|
+
annotations: { title: "Davison Relationship Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
55
55
|
handler: async (args) => {
|
|
56
56
|
validateRequired(args, [
|
|
57
57
|
"person_a_datetime", "person_a_latitude", "person_a_longitude",
|
|
@@ -99,7 +99,7 @@ registerTool({
|
|
|
99
99
|
additionalProperties: false,
|
|
100
100
|
},
|
|
101
101
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
102
|
-
annotations: { title: "Midpoint Composite Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
102
|
+
annotations: { title: "Midpoint Composite Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
103
103
|
handler: async (args) => {
|
|
104
104
|
validateRequired(args, [
|
|
105
105
|
"person_a_datetime", "person_a_latitude", "person_a_longitude",
|
|
@@ -147,7 +147,7 @@ registerTool({
|
|
|
147
147
|
additionalProperties: false,
|
|
148
148
|
},
|
|
149
149
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
150
|
-
annotations: { title: "Synastry House Overlay", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
150
|
+
annotations: { title: "Synastry House Overlay", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
151
151
|
handler: async (args) => {
|
|
152
152
|
validateRequired(args, [
|
|
153
153
|
"person_a_datetime", "person_a_latitude", "person_a_longitude",
|
|
@@ -193,7 +193,7 @@ registerTool({
|
|
|
193
193
|
additionalProperties: false,
|
|
194
194
|
},
|
|
195
195
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
196
|
-
annotations: { title: "Transits to Natal Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
196
|
+
annotations: { title: "Transits to Natal Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
197
197
|
handler: async (args) => {
|
|
198
198
|
validateRequired(args, ["natal_datetime", "natal_latitude", "natal_longitude"]);
|
|
199
199
|
assertPersonZoned("natal", args);
|
|
@@ -42,7 +42,7 @@ registerTool({
|
|
|
42
42
|
additionalProperties: false,
|
|
43
43
|
},
|
|
44
44
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
45
|
-
annotations: { title: "Eclipse Finder", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
45
|
+
annotations: { title: "Eclipse Finder", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
46
46
|
handler: async (args) => {
|
|
47
47
|
validateRequired(args, ["eclipse_type"]);
|
|
48
48
|
validateCoordinates(args, "latitude", "longitude");
|
|
@@ -59,7 +59,7 @@ registerTool({
|
|
|
59
59
|
additionalProperties: false,
|
|
60
60
|
},
|
|
61
61
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
62
|
-
annotations: { title: "Electional Timing Window", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
62
|
+
annotations: { title: "Electional Timing Window", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
63
63
|
handler: async (args) => {
|
|
64
64
|
validateRequired(args, ["start_date", "end_date", "latitude", "longitude"]);
|
|
65
65
|
const query = {
|
|
@@ -110,7 +110,7 @@ registerTool({
|
|
|
110
110
|
additionalProperties: false,
|
|
111
111
|
},
|
|
112
112
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
113
|
-
annotations: { title: "Moment Quality Analysis", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
113
|
+
annotations: { title: "Moment Quality Analysis", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
114
114
|
handler: async (args) => {
|
|
115
115
|
const query = {};
|
|
116
116
|
if (args.date)
|
|
@@ -164,7 +164,7 @@ registerTool({
|
|
|
164
164
|
additionalProperties: false,
|
|
165
165
|
},
|
|
166
166
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
167
|
-
annotations: { title: "Retrograde Station Tracker", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
167
|
+
annotations: { title: "Retrograde Station Tracker", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
168
168
|
handler: async (args) => {
|
|
169
169
|
const query = {};
|
|
170
170
|
// Map human-readable planet names to IDs if needed
|
|
@@ -224,7 +224,7 @@ registerTool({
|
|
|
224
224
|
additionalProperties: false,
|
|
225
225
|
},
|
|
226
226
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
227
|
-
annotations: { title: "Active Aspects Search", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
227
|
+
annotations: { title: "Active Aspects Search", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
228
228
|
handler: async (args) => {
|
|
229
229
|
const query = {};
|
|
230
230
|
if (args.date)
|
|
@@ -302,7 +302,7 @@ registerTool({
|
|
|
302
302
|
additionalProperties: false,
|
|
303
303
|
},
|
|
304
304
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
305
|
-
annotations: { title: "Angle Crossing Search", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
305
|
+
annotations: { title: "Angle Crossing Search", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
306
306
|
handler: async (args) => {
|
|
307
307
|
validateRequired(args, ["latitude", "longitude"]);
|
|
308
308
|
const query = {
|
|
@@ -40,7 +40,7 @@ registerTool({
|
|
|
40
40
|
additionalProperties: false,
|
|
41
41
|
},
|
|
42
42
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
43
|
-
annotations: { title: "Planet Position", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
43
|
+
annotations: { title: "Planet Position", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
44
44
|
handler: async (args) => {
|
|
45
45
|
validateRequired(args, ["planet_id", "datetime"]);
|
|
46
46
|
const body = {
|
|
@@ -89,7 +89,7 @@ registerTool({
|
|
|
89
89
|
additionalProperties: false,
|
|
90
90
|
},
|
|
91
91
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
92
|
-
annotations: { title: "House Cusps", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
92
|
+
annotations: { title: "House Cusps", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
93
93
|
handler: async (args) => {
|
|
94
94
|
validateRequired(args, ["datetime", "latitude", "longitude"]);
|
|
95
95
|
const body = {
|
|
@@ -56,7 +56,7 @@ registerTool({
|
|
|
56
56
|
additionalProperties: false,
|
|
57
57
|
},
|
|
58
58
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
59
|
-
annotations: { title: "Natal Batch Charts", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
59
|
+
annotations: { title: "Natal Batch Charts", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
60
60
|
handler: async (args) => {
|
|
61
61
|
validateRequired(args, ["subjects"]);
|
|
62
62
|
args.subjects.forEach((s, i) => assertZonedDatetime(`subjects[${i}].datetime`, s?.datetime, s?.timezone, `subjects[${i}].timezone`));
|
|
@@ -82,7 +82,7 @@ registerTool({
|
|
|
82
82
|
additionalProperties: false,
|
|
83
83
|
},
|
|
84
84
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
85
|
-
annotations: { title: "Essential Dignities", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
85
|
+
annotations: { title: "Essential Dignities", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
86
86
|
handler: async (args) => {
|
|
87
87
|
validateRequired(args, ["datetime"]);
|
|
88
88
|
return await getActiveClient().post("/ephemeris/dignities", {
|
|
@@ -122,7 +122,7 @@ registerTool({
|
|
|
122
122
|
additionalProperties: false,
|
|
123
123
|
},
|
|
124
124
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
125
|
-
annotations: { title: "Retrograde Status", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
125
|
+
annotations: { title: "Retrograde Status", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
126
126
|
handler: async (args) => {
|
|
127
127
|
validateRequired(args, ["datetime"]);
|
|
128
128
|
const client = getActiveClient();
|
|
@@ -173,7 +173,7 @@ registerTool({
|
|
|
173
173
|
additionalProperties: false,
|
|
174
174
|
},
|
|
175
175
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
176
|
-
annotations: { title: "Midpoints", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
176
|
+
annotations: { title: "Midpoints", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
177
177
|
handler: async (args) => {
|
|
178
178
|
validateRequired(args, ["datetime", "latitude", "longitude"]);
|
|
179
179
|
return await getActiveClient().post("/ephemeris/midpoints", {
|
|
@@ -219,7 +219,7 @@ registerTool({
|
|
|
219
219
|
additionalProperties: false,
|
|
220
220
|
},
|
|
221
221
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
222
|
-
annotations: { title: "Fixed Stars", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
222
|
+
annotations: { title: "Fixed Stars", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
223
223
|
handler: async (args) => {
|
|
224
224
|
validateRequired(args, ["datetime"]);
|
|
225
225
|
// A lone latitude would silently drop the angles from the scan, which is
|
|
@@ -262,7 +262,7 @@ registerTool({
|
|
|
262
262
|
additionalProperties: false,
|
|
263
263
|
},
|
|
264
264
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
265
|
-
annotations: { title: "Hermetic Lots", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
265
|
+
annotations: { title: "Hermetic Lots", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
266
266
|
handler: async (args) => {
|
|
267
267
|
validateRequired(args, ["datetime", "latitude", "longitude"]);
|
|
268
268
|
return await getActiveClient().post("/ephemeris/hermetic-lots", {
|
|
@@ -290,7 +290,7 @@ registerTool({
|
|
|
290
290
|
additionalProperties: false,
|
|
291
291
|
},
|
|
292
292
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
293
|
-
annotations: { title: "Angles & Points", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
293
|
+
annotations: { title: "Angles & Points", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
294
294
|
handler: async (args) => {
|
|
295
295
|
validateRequired(args, ["datetime", "latitude", "longitude"]);
|
|
296
296
|
return await getActiveClient().post("/ephemeris/angles-points", {
|
|
@@ -319,7 +319,7 @@ registerTool({
|
|
|
319
319
|
additionalProperties: false,
|
|
320
320
|
},
|
|
321
321
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
322
|
-
annotations: { title: "Aspect Check", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
322
|
+
annotations: { title: "Aspect Check", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
323
323
|
handler: async (args) => {
|
|
324
324
|
validateRequired(args, ["longitude_1", "longitude_2"]);
|
|
325
325
|
// Backend field names are longitude1 / longitude2 (no underscore)
|
|
@@ -49,7 +49,7 @@ registerTool({
|
|
|
49
49
|
additionalProperties: false,
|
|
50
50
|
},
|
|
51
51
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
52
|
-
annotations: { title: "Human Design Bodygraph", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
52
|
+
annotations: { title: "Human Design Bodygraph", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
53
53
|
handler: async (args) => {
|
|
54
54
|
validateRequired(args, ["datetime"]);
|
|
55
55
|
const body = {
|
|
@@ -58,7 +58,7 @@ registerTool({
|
|
|
58
58
|
additionalProperties: false,
|
|
59
59
|
},
|
|
60
60
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
61
|
-
annotations: { title: "HD Planetary Return", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
61
|
+
annotations: { title: "HD Planetary Return", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
62
62
|
handler: async (args) => {
|
|
63
63
|
validateRequired(args, ["planet", "datetime", "return_year"]);
|
|
64
64
|
return await getActiveClient().request("POST", "/human-design/cycles/return", {
|
|
@@ -112,7 +112,7 @@ registerTool({
|
|
|
112
112
|
additionalProperties: false,
|
|
113
113
|
},
|
|
114
114
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
115
|
-
annotations: { title: "HD Opposition Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
115
|
+
annotations: { title: "HD Opposition Chart", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
116
116
|
handler: async (args) => {
|
|
117
117
|
validateRequired(args, ["planet", "datetime", "target_year"]);
|
|
118
118
|
return await getActiveClient().request("POST", "/human-design/cycles/opposition", {
|
|
@@ -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 = {
|
|
@@ -39,7 +39,7 @@ registerTool({
|
|
|
39
39
|
additionalProperties: false,
|
|
40
40
|
},
|
|
41
41
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
42
|
-
annotations: { title: "Moon Phase", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
42
|
+
annotations: { title: "Moon Phase", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
43
43
|
handler: async (args) => {
|
|
44
44
|
validateCoordinates(args, "latitude", "longitude");
|
|
45
45
|
const params = {};
|
|
@@ -104,7 +104,7 @@ registerTool({
|
|
|
104
104
|
additionalProperties: false,
|
|
105
105
|
},
|
|
106
106
|
outputSchema: OUTPUT_SCHEMA_JSON,
|
|
107
|
-
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 },
|
|
108
108
|
handler: async (args) => {
|
|
109
109
|
const PHASE_LABELS = {
|
|
110
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 = {};
|