@openephemeris/mcp-server 3.13.9 → 3.13.10
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/README.md +2 -2
- package/config/dev-allowlist.json +28 -4
- package/dist/index.js +45 -0
- package/dist/oauth/dcr.d.ts +11 -0
- package/dist/oauth/dcr.js +49 -0
- package/dist/oauth/discovery.d.ts +11 -0
- package/dist/oauth/discovery.js +40 -0
- package/dist/oauth/pkce.d.ts +18 -0
- package/dist/oauth/pkce.js +34 -0
- package/dist/oauth/rate-limit.d.ts +20 -0
- package/dist/oauth/rate-limit.js +65 -0
- package/dist/oauth/store.d.ts +68 -0
- package/dist/oauth/store.js +247 -0
- package/dist/oauth/supabase-jwt.d.ts +39 -0
- package/dist/oauth/supabase-jwt.js +194 -0
- package/dist/oauth/token.d.ts +21 -0
- package/dist/oauth/token.js +213 -0
- package/dist/prompts.js +171 -159
- package/dist/server-sse.js +134 -36
- package/dist/tools/apps/bazi-app.d.ts +23 -0
- package/dist/tools/apps/bazi-app.js +224 -0
- package/dist/tools/apps/bi-wheel-app.d.ts +14 -7
- package/dist/tools/apps/bi-wheel-app.js +293 -108
- package/dist/tools/apps/bodygraph-app.js +38 -3
- package/dist/tools/apps/moon-phase-app.d.ts +19 -0
- package/dist/tools/apps/moon-phase-app.js +190 -0
- package/dist/tools/apps/transit-timeline-app.d.ts +20 -0
- package/dist/tools/apps/transit-timeline-app.js +243 -0
- package/dist/tools/apps/vedic-chart-app.d.ts +17 -0
- package/dist/tools/apps/vedic-chart-app.js +226 -0
- package/dist/tools/index.js +4 -0
- package/dist/tools/specialized/acg.js +2 -2
- package/dist/tools/specialized/bazi.js +367 -44
- 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 +4 -4
- 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/dist/ui/bazi.html +213 -0
- package/dist/ui/bi-wheel.html +762 -489
- package/dist/ui/bodygraph.html +1788 -1649
- package/dist/ui/chart-wheel.html +1772 -1593
- package/dist/ui/moon-phase.html +6758 -0
- package/dist/ui/transit-timeline.html +6835 -0
- package/dist/ui/vedic-chart.html +210 -0
- package/package.json +2 -2
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* vedic-chart-app.ts — MCP App tool registration for the Vedic Jyotish Chart Explorer.
|
|
3
|
+
*
|
|
4
|
+
* Registers 1 tool:
|
|
5
|
+
* • explore_vedic_chart — primary entry point [model + app visible]
|
|
6
|
+
* Calls POST /vedic/chart and returns a data payload + UI resource URI
|
|
7
|
+
* so Claude Desktop can render the interactive South Indian Rashi grid.
|
|
8
|
+
*
|
|
9
|
+
* Also exports resource helpers (getVedicChartBundle, etc.) for use in
|
|
10
|
+
* server-sse.ts resource listing and reading.
|
|
11
|
+
*/
|
|
12
|
+
import fs from "node:fs";
|
|
13
|
+
import path from "node:path";
|
|
14
|
+
import { fileURLToPath } from "node:url";
|
|
15
|
+
import { registerTool, SERVER_VERSION } from "../index.js";
|
|
16
|
+
import { getActiveClient } from "../../backend/client.js";
|
|
17
|
+
// ── Constants ─────────────────────────────────────────────────────────────────
|
|
18
|
+
export const VEDIC_CHART_RESOURCE_URI = "ui://openephemeris/vedic-chart";
|
|
19
|
+
export const VEDIC_CHART_MIME_TYPE = "text/html;profile=mcp-app";
|
|
20
|
+
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
21
|
+
const BUNDLE_PATHS = [
|
|
22
|
+
path.resolve(here, "..", "..", "..", "dist", "ui", "vedic-chart.html"),
|
|
23
|
+
];
|
|
24
|
+
function findBundlePath() {
|
|
25
|
+
for (const p of BUNDLE_PATHS) {
|
|
26
|
+
if (fs.existsSync(p))
|
|
27
|
+
return p;
|
|
28
|
+
}
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
let cachedBundle = null;
|
|
32
|
+
/** Read the pre-built HTML bundle. Returns null if not yet built. */
|
|
33
|
+
export function getVedicChartBundle() {
|
|
34
|
+
if (cachedBundle)
|
|
35
|
+
return cachedBundle;
|
|
36
|
+
const bundlePath = findBundlePath();
|
|
37
|
+
if (!bundlePath)
|
|
38
|
+
return null;
|
|
39
|
+
try {
|
|
40
|
+
cachedBundle = fs.readFileSync(bundlePath, "utf-8");
|
|
41
|
+
return cachedBundle;
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/** Reset cache (useful in dev watch mode or tests). */
|
|
48
|
+
export function clearVedicChartBundleCache() {
|
|
49
|
+
cachedBundle = null;
|
|
50
|
+
}
|
|
51
|
+
function parseVedicArgs(args) {
|
|
52
|
+
const { datetime, latitude, longitude, ayanamsa } = args;
|
|
53
|
+
if (!datetime) {
|
|
54
|
+
throw new Error("datetime is required. Provide an ISO 8601 datetime in UTC, " +
|
|
55
|
+
"e.g. datetime='1987-07-15T14:30:00Z'.");
|
|
56
|
+
}
|
|
57
|
+
if (latitude == null || longitude == null) {
|
|
58
|
+
throw new Error("latitude and longitude are required for Vedic chart calculation. " +
|
|
59
|
+
"Example: latitude=28.6, longitude=77.2 (New Delhi).");
|
|
60
|
+
}
|
|
61
|
+
return { datetime, latitude, longitude, ayanamsa: ayanamsa || undefined };
|
|
62
|
+
}
|
|
63
|
+
// ── Summary builder ──────────────────────────────────────────────────────────
|
|
64
|
+
// Convert a sidereal longitude (0–360°) to the Western sign name
|
|
65
|
+
function lonToSignName(lon) {
|
|
66
|
+
const SIGNS = [
|
|
67
|
+
"Aries", "Taurus", "Gemini", "Cancer", "Leo", "Virgo",
|
|
68
|
+
"Libra", "Scorpio", "Sagittarius", "Capricorn", "Aquarius", "Pisces",
|
|
69
|
+
];
|
|
70
|
+
const idx = Math.floor(((lon % 360) + 360) % 360 / 30) % 12;
|
|
71
|
+
return SIGNS[idx];
|
|
72
|
+
}
|
|
73
|
+
function buildVedicSummary(data) {
|
|
74
|
+
const planets = data.planets || [];
|
|
75
|
+
const metadata = data.metadata || {};
|
|
76
|
+
// lagna is a degree float from the backend — convert to sign name
|
|
77
|
+
const lagnaSign = typeof metadata.lagna === "number"
|
|
78
|
+
? lonToSignName(metadata.lagna)
|
|
79
|
+
: metadata.lagna || "unknown";
|
|
80
|
+
// Backend returns "ayanamsha" (with extra h) — normalise
|
|
81
|
+
const ayanamsa = metadata.ayanamsa || metadata.ayanamsha || "Lahiri";
|
|
82
|
+
const ayanamsaVal = metadata.ayanamsa_value != null
|
|
83
|
+
? " (" + metadata.ayanamsa_value.toFixed(2) + "°)"
|
|
84
|
+
: metadata.correction != null
|
|
85
|
+
? " (" + metadata.correction.toFixed(2) + "°)"
|
|
86
|
+
: "";
|
|
87
|
+
let summary = "**Vedic Jyotish Chart** — Lagna: **" + lagnaSign + "** · Ayanamsa: " +
|
|
88
|
+
ayanamsa + ayanamsaVal + "\n\n";
|
|
89
|
+
// Planet placement table
|
|
90
|
+
if (planets.length > 0) {
|
|
91
|
+
summary += "| Planet | Rashi | Degree | Nakshatra | Pada |\n";
|
|
92
|
+
summary += "|--------|-------|--------|-----------|------|\n";
|
|
93
|
+
for (const p of planets) {
|
|
94
|
+
const retroMark = p.is_retrograde ? " ℞" : "";
|
|
95
|
+
summary +=
|
|
96
|
+
"| " + capFirst(String(p.planet)) + retroMark +
|
|
97
|
+
" | " + (p.rashi_western || p.rashi || "?") +
|
|
98
|
+
" | " + (typeof p.rashi_degree === "number" ? p.rashi_degree.toFixed(2) + "°" : "?") +
|
|
99
|
+
" | " + (p.nakshatra?.name || "?") +
|
|
100
|
+
" | " + (p.nakshatra?.pada || "?") +
|
|
101
|
+
" |\n";
|
|
102
|
+
}
|
|
103
|
+
summary += "\n";
|
|
104
|
+
}
|
|
105
|
+
summary += "Click on any Rashi cell to explore the planets placed there.";
|
|
106
|
+
return summary;
|
|
107
|
+
}
|
|
108
|
+
function capFirst(s) {
|
|
109
|
+
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
110
|
+
}
|
|
111
|
+
// ── Tool: explore_vedic_chart ─────────────────────────────────────────────────
|
|
112
|
+
registerTool({
|
|
113
|
+
name: "explore_vedic_chart",
|
|
114
|
+
description: "Generate an interactive Vedic Jyotish (South Indian) Rashi chart visualization.\n\n" +
|
|
115
|
+
"Renders a 4×4 fixed-sign grid with:\n" +
|
|
116
|
+
" • All nine Jyotish planets (Sun through Ketu) placed in their Rashi\n" +
|
|
117
|
+
" • Lagna (Ascendant) cell marked with a gold diagonal\n" +
|
|
118
|
+
" • Sanskrit/Devanagari sign labels toggle\n" +
|
|
119
|
+
" • Click any Rashi cell → detailed planet info drawer\n" +
|
|
120
|
+
" (degree, Nakshatra, Pada, lord, Navamsa sign, dignity)\n" +
|
|
121
|
+
" • Ask Claude buttons for Lagna, Moon/Nakshatra, and full chart interpretation\n" +
|
|
122
|
+
" • Ayanamsa system displayed (Lahiri by default)\n\n" +
|
|
123
|
+
"CREDIT COST: 1 credit.\n\n" +
|
|
124
|
+
"Use this for a rich, interactive Vedic chart experience in MCP Apps-capable hosts " +
|
|
125
|
+
"(Claude Desktop). Falls back to a markdown table summary in other hosts.",
|
|
126
|
+
inputSchema: {
|
|
127
|
+
type: "object",
|
|
128
|
+
properties: {
|
|
129
|
+
datetime: {
|
|
130
|
+
type: "string",
|
|
131
|
+
description: "Birth date and time as ISO 8601, e.g. '1987-07-15T14:30:00Z'. " +
|
|
132
|
+
"Always include time when known — it determines the Lagna (Ascendant).",
|
|
133
|
+
},
|
|
134
|
+
latitude: {
|
|
135
|
+
type: "number",
|
|
136
|
+
description: "Birth latitude in decimal degrees, e.g. 28.6 for New Delhi.",
|
|
137
|
+
},
|
|
138
|
+
longitude: {
|
|
139
|
+
type: "number",
|
|
140
|
+
description: "Birth longitude in decimal degrees, e.g. 77.2 for New Delhi.",
|
|
141
|
+
},
|
|
142
|
+
ayanamsa: {
|
|
143
|
+
type: "string",
|
|
144
|
+
enum: ["lahiri", "fagan_bradley", "krishnamurti", "raman", "yukteshwar"],
|
|
145
|
+
description: "Ayanamsa system for sidereal calculation. " +
|
|
146
|
+
"Options: 'lahiri' (default, most common), 'raman', 'krishnamurti', 'fagan_bradley', 'yukteshwar'.",
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
required: ["datetime", "latitude", "longitude"],
|
|
150
|
+
additionalProperties: false,
|
|
151
|
+
},
|
|
152
|
+
annotations: {
|
|
153
|
+
title: "Interactive Vedic Jyotish Chart",
|
|
154
|
+
readOnlyHint: true,
|
|
155
|
+
destructiveHint: false,
|
|
156
|
+
idempotentHint: true,
|
|
157
|
+
openWorldHint: false,
|
|
158
|
+
},
|
|
159
|
+
_meta: {
|
|
160
|
+
ui: {
|
|
161
|
+
resourceUri: VEDIC_CHART_RESOURCE_URI,
|
|
162
|
+
visibility: ["model", "app"],
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
handler: async (args) => {
|
|
166
|
+
const { datetime, latitude, longitude, ayanamsa } = parseVedicArgs(args);
|
|
167
|
+
const client = getActiveClient();
|
|
168
|
+
// Backend field is datetime_utc (matches vedic.ts specialized tool)
|
|
169
|
+
const body = {
|
|
170
|
+
datetime_utc: datetime,
|
|
171
|
+
latitude,
|
|
172
|
+
longitude,
|
|
173
|
+
};
|
|
174
|
+
if (ayanamsa)
|
|
175
|
+
body.ayanamsa = ayanamsa;
|
|
176
|
+
const result = await client.request("POST", "/vedic/chart", { data: body });
|
|
177
|
+
const rawMeta = result.metadata || {};
|
|
178
|
+
// Backend returns lagna as a degree float (e.g. 213.4) but the iframe
|
|
179
|
+
// expects a sign name string (e.g. "Scorpio") for cell matching.
|
|
180
|
+
const lagnaRaw = rawMeta.lagna;
|
|
181
|
+
const lagnaSign = typeof lagnaRaw === "number"
|
|
182
|
+
? lonToSignName(lagnaRaw)
|
|
183
|
+
: lagnaRaw || "";
|
|
184
|
+
// Backend returns "ayanamsha" (extra h) — normalise to "ayanamsa".
|
|
185
|
+
const ayanamsaName = rawMeta.ayanamsa || rawMeta.ayanamsha || "Lahiri";
|
|
186
|
+
const normalizedMeta = {
|
|
187
|
+
...rawMeta,
|
|
188
|
+
lagna: lagnaSign,
|
|
189
|
+
ayanamsa: ayanamsaName,
|
|
190
|
+
// Expose correction as ayanamsa_value so the iframe can show the degree
|
|
191
|
+
ayanamsa_value: rawMeta.ayanamsa_value ?? rawMeta.correction ?? null,
|
|
192
|
+
};
|
|
193
|
+
// Build a Set from the retrograde_planets list the Go handler populated.
|
|
194
|
+
const retrogradeList = Array.isArray(rawMeta.retrograde_planets)
|
|
195
|
+
? rawMeta.retrograde_planets
|
|
196
|
+
: [];
|
|
197
|
+
const retrogradeSet = new Set(retrogradeList);
|
|
198
|
+
const uiPayload = {
|
|
199
|
+
// Stamp is_retrograde on each planet using the retrograde_planets list
|
|
200
|
+
// from metadata — the Go struct has no such field, so it lives in metadata.
|
|
201
|
+
planets: (result.planets || []).map((p) => ({
|
|
202
|
+
...p,
|
|
203
|
+
is_retrograde: retrogradeSet.has(String(p.planet)),
|
|
204
|
+
})),
|
|
205
|
+
metadata: normalizedMeta,
|
|
206
|
+
server_version: SERVER_VERSION,
|
|
207
|
+
};
|
|
208
|
+
const summary = buildVedicSummary(uiPayload);
|
|
209
|
+
const bundleAvailable = Boolean(getVedicChartBundle());
|
|
210
|
+
if (bundleAvailable) {
|
|
211
|
+
return {
|
|
212
|
+
content: [
|
|
213
|
+
{ type: "text", text: summary },
|
|
214
|
+
// Second text block is injected as window.__VEDIC_CHART_DATA__ by ext-apps SDK
|
|
215
|
+
{ type: "text", text: JSON.stringify(uiPayload) },
|
|
216
|
+
],
|
|
217
|
+
_meta: {
|
|
218
|
+
"ui/resourceUri": VEDIC_CHART_RESOURCE_URI,
|
|
219
|
+
ui: { resourceUri: VEDIC_CHART_RESOURCE_URI },
|
|
220
|
+
},
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
// Fallback: text-only table
|
|
224
|
+
return { content: [{ type: "text", text: summary }] };
|
|
225
|
+
},
|
|
226
|
+
});
|
package/dist/tools/index.js
CHANGED
|
@@ -74,6 +74,10 @@ export async function initTools(profile) {
|
|
|
74
74
|
await import("./apps/chart-wheel-app.js");
|
|
75
75
|
await import("./apps/bodygraph-app.js");
|
|
76
76
|
await import("./apps/bi-wheel-app.js");
|
|
77
|
+
await import("./apps/transit-timeline-app.js");
|
|
78
|
+
await import("./apps/moon-phase-app.js");
|
|
79
|
+
await import("./apps/bazi-app.js");
|
|
80
|
+
await import("./apps/vedic-chart-app.js");
|
|
77
81
|
await import("./apps/location-tools.js");
|
|
78
82
|
}
|
|
79
83
|
}
|
|
@@ -54,7 +54,7 @@ registerTool({
|
|
|
54
54
|
required: ["birth_datetime", "birth_latitude", "birth_longitude"],
|
|
55
55
|
additionalProperties: false,
|
|
56
56
|
},
|
|
57
|
-
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
57
|
+
annotations: { title: "Astrocartography Lines", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
58
58
|
handler: async (args) => {
|
|
59
59
|
validateRequired(args, ["birth_datetime", "birth_latitude", "birth_longitude"]);
|
|
60
60
|
const body = {
|
|
@@ -147,7 +147,7 @@ registerTool({
|
|
|
147
147
|
required: ["birth_datetime", "birth_latitude", "birth_longitude", "query_latitude", "query_longitude"],
|
|
148
148
|
additionalProperties: false,
|
|
149
149
|
},
|
|
150
|
-
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
150
|
+
annotations: { title: "Astrocartography Location Hits", readOnlyHint: true, destructiveHint: false, idempotentHint: true },
|
|
151
151
|
handler: async (args) => {
|
|
152
152
|
validateRequired(args, ["birth_datetime", "birth_latitude", "birth_longitude", "query_latitude", "query_longitude"]);
|
|
153
153
|
const body = {
|