Natal chart engine that cross-verifies every result three independent ways — and refuses to answer when it cannot. Handles historical DST (Taiwan 1979, China 1986-1991) that most astrology tools get wrong by a full hour. Ships as both a library and an MCP server.
Four well-named, verb-led tools with excellent descriptions (150 - 350 chars each). All parameters have types and descriptions. Input schemas are complete with regex patterns and numeric bounds. Output schemas are documented in code comments. Error handling is explicit (cross-verification, DST diagnostics). Main gaps: no tool annotations (readOnlyHint/destructiveHint), no output schema formally declared in MCP registration, and parameter descriptions could be more concise for LLM parsing efficiency.
For users who do not know their birth time. Returns only what is genuinely knowable without it, and explicitly lists what is not: ascendant, midheaven and all house positions are omitted with reasons rather than estimated. Also reports whether the Moon changed sign during that day — it does on nearly half of all dates, which means the moon sign itself is undetermined without a time. Never substitute noon and present the result as fact; that is exactly what this tool exists to prevent.
Compute a full natal/birth chart: ten planets with sign, degree, house and retrograde status, plus ascendant, midheaven and twelve house cusps. Every result is cross-checked by two independent astronomy implementations and the call FAILS rather than returning a chart when they disagree. Use this whenever a user asks for a birth chart, rising sign, or planetary placements — do not attempt the arithmetic yourself. Requires an exact birth time; if the time is unknown use calculate_chart_without_birth_time instead.
Resolve a local birth date and time to UTC using historical timezone rules, and report whether daylight saving time was actually in effect on that date. This is the single most common source of wrong charts: many tools apply the PRESENT-DAY offset to a past date. Taiwan observed DST 1945-1961 and 1974-1979, mainland China 1986-1991, Japan 1948-1951 — a birth inside those windows is an hour off in tools that ignore them, which moves the ascendant about 15 degrees. Use this to explain WHY two charts differ.
Recompute the ascendant along a third path that imports no astrology library at all — pure spherical geometry, the intersection of the ecliptic with the eastern horizon — and report how far it lands from the primary engine. Optionally pass a value produced ELSEWHERE (another website, an app, a printed chart) as `claim` and this will tell you whether it holds up and, when it does not, name the likely cause. Use this when a user says two sites disagree about their rising sign, doubts a result, or asks which one is correct. Accepts claims like "Virgo", "處女座", "12 Leo", "Leo 12°34'" or a bare ecliptic longitude.
Tool annotations missing: no readOnlyHint, destructiveHint, or idempotentHint declared in MCP registration. All four tools are read-only and idempotent, but this is not signaled to clients.
Output schemas not formally declared in MCP tool definitions. Descriptions mention what is returned (e.g., 'full natal chart with ten planets'), but JSON Schema for response structure is absent from the MCP registration.
Parameter descriptions are verbose (100+ chars for some). LLMs parse concise descriptions more reliably. E.g., 'IANA timezone of the BIRTHPLACE, e.g. Asia/Taipei. Never the user's current zone, people are routinely asked about a birth in another country.' could be shortened to 'IANA timezone of birthplace (e.g., Asia/Taipei), not user's current zone.'
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | B | 79 | 2026-07-28+ | v2 |
No explicit error recovery guidance in tool descriptions. While the code cross-verifies and fails on disagreement, the description does not tell the LLM what to do if a call fails (e.g., 'If verification fails, try inspect_historical_timezone to diagnose DST issues').
verify_ascendant 'claim' parameter is optional but its format is under-specified. Description lists examples ('Virgo', '12 Leo', 'Leo 12°34'') but does not formally constrain the input grammar, risking LLM hallucination of invalid formats.