@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.
Files changed (34) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/tools/apps/bazi-app.js +1 -1
  3. package/dist/tools/apps/bi-wheel-app.js +5 -5
  4. package/dist/tools/apps/bodygraph-app.js +8 -8
  5. package/dist/tools/apps/chart-wheel-app.js +4 -4
  6. package/dist/tools/apps/location-tools.js +2 -2
  7. package/dist/tools/apps/moon-phase-app.js +1 -1
  8. package/dist/tools/apps/vedic-chart-app.js +1 -1
  9. package/dist/tools/auth.js +8 -0
  10. package/dist/tools/dev.js +15 -5
  11. package/dist/tools/specialized/account.js +5 -1
  12. package/dist/tools/specialized/acg.js +2 -2
  13. package/dist/tools/specialized/bazi.js +7 -7
  14. package/dist/tools/specialized/bi_wheel.js +1 -1
  15. package/dist/tools/specialized/chart_wheel.js +1 -1
  16. package/dist/tools/specialized/comparative.js +4 -4
  17. package/dist/tools/specialized/eclipse.js +1 -1
  18. package/dist/tools/specialized/electional.js +5 -5
  19. package/dist/tools/specialized/ephemeris_core.js +2 -2
  20. package/dist/tools/specialized/ephemeris_extended.js +8 -8
  21. package/dist/tools/specialized/hd_bodygraph.js +1 -1
  22. package/dist/tools/specialized/hd_cycles.js +2 -2
  23. package/dist/tools/specialized/hd_group.js +2 -2
  24. package/dist/tools/specialized/human_design.js +1 -1
  25. package/dist/tools/specialized/moon.js +2 -2
  26. package/dist/tools/specialized/natal.js +1 -1
  27. package/dist/tools/specialized/progressed.js +1 -1
  28. package/dist/tools/specialized/relocation.js +1 -1
  29. package/dist/tools/specialized/returns.js +3 -3
  30. package/dist/tools/specialized/synastry.js +1 -1
  31. package/dist/tools/specialized/transits.js +1 -1
  32. package/dist/tools/specialized/vedic.js +1 -1
  33. package/dist/tools/specialized/venus_star_points.js +6 -6
  34. 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();
@@ -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
- annotations: { title: "API Read", readOnlyHint: true, openWorldHint: true },
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
- annotations: { title: "API Write", readOnlyHint: false, openWorldHint: true },
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 = {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openephemeris/mcp-server",
3
- "version": "4.8.0",
3
+ "version": "4.8.1",
4
4
  "description": "Model Context Protocol server for the Open Ephemeris astronomical computation API",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",