# astro-mcp MCP server for astrological chart calculations. Consumes `ephemeris-mcp:get_sky_state` via MCP-over-SSE client and exposes calculated astrological data (natal charts, transits, synastry, transit previews) as structured JSON tools. **Version: 0.8.0** ## Quick Start ```bash python -m venv .venv source .venv/bin/activate pip install -r requirements.txt ./run.sh ``` Server listens on port 7016 (configurable via `ASTRO_PORT`). ## Docker ```bash docker compose up --build ``` Health check: `GET http://localhost:7016/health` ## Configuration (.env) | Variable | Default | Description | |---|---|---| | `ASTRO_HOST` | `0.0.0.0` | Bind address | | `ASTRO_PORT` | `7016` | Listen port | | `ASTRO_DATA_DIR` | `./data` | SQLite DB directory | | `ASTRO_LOG_DIR` | `./logs` | Log file directory | | `EPHEMERIS_MCP_URL` | `http://192.168.0.200:7015/mcp/sse` | Ephemeris MCP endpoint | | `GEONAMES_USERNAME` | *(empty)* | GeoNames username for birthplace autocomplete | | `DASHBOARD_24H_TIME` | `true` | Use 24h time format in forms (false = 12h with AM/PM) | ## MCP Endpoint SSE transport at `http://localhost:7016/mcp/sse` ## Tools ### Core tools (raw birth data) | Tool | Description | |---|---| | `get_planetary_positions` | Planetary positions with zodiac signs, degrees, retrograde flags | | `calculate_natal_chart` | Complete natal chart (planets, houses, aspects, angles) | | `calculate_transit_chart` | Transit chart with natal-to-transit aspects | | `calculate_synastry_chart` | Relationship chart for two people | | `calculate_composite_chart` | Composite chart via midpoint method | | `get_transit_preview` | Daily transit-to-natal aspect snapshot with significance scoring | | `person_manage` | CRUD for persons database | | `list_house_systems` | List supported house systems | ### _byId tools (database-backed) Each core chart tool has a `_byId` variant that accepts a `person_id` (from the persons database) instead of raw birth data. All other optional parameters override the defaults. | Tool | Description | |---|---| | `calculate_natal_chart_by_id` | Natal chart by person_id | | `calculate_transit_chart_by_id` | Transit chart by person_id + transit_datetime | | `calculate_synastry_chart_by_id` | Synastry chart for person1_id + person2_id | | `calculate_composite_chart_by_id` | Composite chart for person1_id + person2_id | | `get_transit_preview_by_id` | Transit preview by person_id + date range | ## Person Database ### Schema ```sql CREATE TABLE persons ( id TEXT PRIMARY KEY, name TEXT NOT NULL, nickname TEXT UNIQUE, birth_datetime TEXT NOT NULL, latitude REAL NOT NULL, longitude REAL NOT NULL, elevation REAL DEFAULT 0.0, birthplace TEXT, alive BOOLEAN DEFAULT 1, private BOOLEAN DEFAULT 0, gender TEXT, description TEXT, notes TEXT, timezone TEXT, birth_time_known BOOLEAN DEFAULT 1, created_at TEXT NOT NULL, updated_at TEXT ); ``` All columns added via non-destructive `ALTER TABLE` migrations. ### person_manage tool Supports actions: `add`, `get` (by id or nickname), `list`, `update`, `delete`. Example workflow: ``` person_manage(action="add", name="Me", birth_datetime="1965-07-02T00:05:00+02:00", birthplace="Graz, Austria", latitude=47.076668, longitude=15.421371) => {"person": {"id": "abc12345", ...}} # Then use the _byId tools: calculate_natal_chart_by_id(person_id="abc12345") calculate_transit_chart_by_id(person_id="abc12345", transit_datetime="2026-06-02T12:00:00") ``` ## Dashboard Person management dashboard at `http://localhost:7016/dashboard` ### Features - **Person list** with name, nickname, birth date, location, gender, status badges - **Add/Edit form** with: - Native date picker + time input (12h or 24h based on `DASHBOARD_24H_TIME`) - Timezone select with 50+ IANA zones grouped by region - Live UTC offset display (e.g. "UTC+01:00 (CEST)") - GeoNames autocomplete for birthplace (requires `GEONAMES_USERNAME`) — auto-fills lat/lon/elevation/timezone - **Detail view** with all fields, notes, metadata - **Export** individual persons or all persons as JSON - **Import** persons from JSON file (single object or array) - **Delete** with confirmation dialog ### Import/Export Format ```json [ { "name": "John Doe", "nickname": "john", "birth_datetime": "1990-05-15T08:30:00+02:00", "birthplace": "Vienna, Austria", "latitude": 48.2082, "longitude": 16.3738, "elevation": 171, "alive": true, "private": false, "gender": "male", "description": "A sample person", "notes": "Some notes here", "timezone": "Europe/Vienna", "birth_time_known": true } ] ``` Required fields: `name`, `birth_datetime`, `latitude`, `longitude`. All others are optional.