# Astro-MCP Server Guide ## Overview Astro-MCP is an astrological chart calculation server. It consumes birth data and returns planetary positions, house cusps, angles, and aspects. All computation is delegated to a separate **ephemeris-mcp** server which runs the Swiss Ephemeris library. ## Architecture ``` User / Agent | v astro-mcp (this server) | MCP SSE v ephemeris-mcp (Swiss Ephemeris backend) ``` - **astro-mcp** handles: person database, chart interpretation, rendering, timezone conversion, MCP tool interface - **ephemeris-mcp** handles: raw astronomical computation (planetary positions, house cusps, sidereal time) ## Timezone Rules (CRITICAL) ### Single Conversion Point **`_get_person_birth_data()`** is the ONLY function that converts stored birth datetimes to UTC. It reads the naive local time and IANA timezone name from the persons database, combines them, and returns a UTC datetime. All `_byId` chart tools call this function. **No other function performs timezone conversion.** ### Database Storage Format - `birth_datetime`: naive local time, NO offset (e.g. `"1965-07-02T00:05:00"`) - `timezone`: IANA timezone name (e.g. `"Europe/Vienna"`, `"America/New_York"`) - `longitude`: used as fallback for LMT when timezone is missing ### Direct-Call Tools Tools that accept `birth_datetime` as a parameter (e.g. `calculate_natal_chart`, `calculate_transit_chart`) expect **UTC or offset-aware datetimes**. The caller is responsible for conversion. Use ISO 8601 format: - UTC: `"1965-07-01T23:05:00Z"` or `"1965-07-01T23:05:00+00:00"` - Offset-aware: `"1965-07-02T00:05:00+01:00"` ### _byId Tools Tools that look up persons by ID/nickname (e.g. `calculate_natal_chart_by_id`) automatically convert to UTC. Just pass the person identifier. ### Person Management #### Adding a Person Use `person_manage` with `action: "add"`. Required fields: - `name`: Full name - `birth_datetime`: ISO 8601 **naive local time** (no offset, e.g. `"1990-05-15T10:30:00"`) - `latitude`, `longitude`: Birth coordinates - `tz`: IANA timezone name (e.g. `"Europe/Vienna"`, `"America/New_York"`) Optional: `nickname`, `birthplace`, `elevation`, `gender`, `description`, `notes`, `birth_time_known`. #### Datetime Convention (CRITICAL) The persons database stores **naive local time** + **IANA timezone name**. The conversion to UTC happens exactly once, inside `_get_person_birth_data()`, which combines them using `zoneinfo.ZoneInfo`. Rules: - `birth_datetime` in the DB: **always naive, always local** (no `Z`, no `+01:00`) - `timezone`: IANA name (e.g. `"America/Chicago"`, `"Europe/Berlin"`) - `longitude`: fallback for LMT only when `timezone` is NULL (pre-1900 dates) **Do NOT store UTC in the DB.** Do NOT add an offset to `birth_datetime`. If you store `"1953-03-23T03:05:00+00:00"` (UTC), the conversion will treat it as already-UTC and the chart will be wrong. Instead store `"1953-03-23T21:05:00"` (local Chicago time) with `tz="America/Chicago"`. **Historical note:** Before ~1890, IANA timezones use Local Mean Time (LMT) which can differ from modern UTC offsets by minutes. For example, Einstein's birth in Ulm (1879) is LMT = UTC+0:53:28, not the modern CET (UTC+1). The `zoneinfo` module handles this correctly when given the IANA name. Always provide `tz` for historical dates — do not compute the UTC offset manually. #### Listing and Updating - `person_manage` with `action: "list"` — list all persons - `person_manage` with `action: "get"` — retrieve by ID or nickname - `person_manage` with `action: "update"` — modify fields - `person_manage` with `action: "delete"` — remove person ## Tool Categories ### Data-Only Tools (return JSON) | Tool | Description | |------|-------------| | `get_sky_state` | Raw planetary positions + houses for a datetime/location | | `calculate_natal_chart` | Full natal chart: planets, houses, aspects, angles | | `calculate_transit_chart` | Transit-to-natal aspects | | `calculate_synastry_chart` | Relationship chart for two people | | `calculate_composite_chart` | Composite (midpoint) chart | | `calculate_davison_chart` | Davison (space-time midpoint) chart | | `get_transit_preview` | Daily transit snapshots over a date range | | `get_karmic_relationship_summary` | Karmic analysis for a relationship | ### _byId Variants (lookup person from DB) Same as above but with `_byId` suffix. Accept `person_id` (or nickname) instead of birth data. Automatically handle timezone conversion. ### Rendering Tools (return SVG) | Tool | Description | |------|-------------| | `render_natal_chart` | SVG natal chart wheel | | `render_transit_chart` | SVG transit chart | | `render_synastry_chart` | SVG synastry chart | | `render_composite_chart` | SVG composite chart | | `render_davison_chart` | SVG Davison chart | Each has a `_byId` variant. ### Utility Tools | Tool | Description | |------|-------------| | `person_manage` | CRUD for persons database | | `list_house_systems` | List supported house systems (Placidus, Koch, etc.) | ## House Systems Supported house system codes: P (Placidus), K (Koch), E (Equal), W (Whole Sign), A (Alcabitius), C (Campanus), M (Morinus), R (Porphyry), and more. Use `list_house_systems` for the full list. Default is Placidus. ## Common Workflows ### Natal Chart for a Known Person ``` 1. person_manage(action="add", name="...", birth_datetime="...", latitude=..., longitude=..., tz="...") 2. calculate_natal_chart_by_id(person_id="...", include_overview=true) ``` ### Natal Chart for a One-Off Calculation ``` calculate_natal_chart( birth_datetime="1990-05-15T10:30:00+01:00", # UTC or offset-aware latitude=47.07, longitude=15.42, include_overview=true ) ``` ### Transit Chart ``` calculate_transit_chart_by_id( person_id="...", transit_datetime="2026-06-07T12:00:00Z" # UTC ) ``` ### Relationship Analysis ``` calculate_synastry_chart_by_id( person1_id="...", person2_id="...", include_davison_full=true ) ``` ### Rendered Chart ``` render_natal_chart_by_id( person_id="...", style="modern", color_mode="color", size=800 ) ``` ## Resources (fetch with astro:// URI) | URI | Content | |-----|---------| | `astro://guides/natal-astrology` | Natal chart interpretation guide | | `astro://guides/karmic-astrology` | Karmic astrology guide | | `astro://guides/relationship-astrology` | Relationship astrology guide | | `astro://guides/financial-astrology` | Financial astrology guide | ## Error Handling All tools return `{"error": "message"}` on failure. Common errors: - `"person not found: ..."` — invalid person_id or nickname - `"add requires: name, birth_datetime, latitude, longitude"` — missing fields - `"empty_response"` — ephemeris server unreachable ## Tips 1. Always use `_byId` tools when working with stored persons — they handle timezone conversion automatically. 2. For direct-call tools, pass UTC datetimes to avoid ambiguity. 3. The `include_overview` flag adds element/modality/hemisphere balance, stelliums, empty houses, chart ruler, and house rulers. 4. The `include_patterns` flag adds T-square, Grand Trine, Grand Cross, Yod detection and chart shape classification. 5. The `include_karmic` flag adds nodal axis, Saturn, Pluto polarity point, Part of Fortune, and 12th house analysis. 6. Use `top_n_aspects` to limit aspect output to the N tightest by orb.