Skip to main content
Glama
akuttruff

astrology-mcp

by akuttruff
README.md
# Astrology MCP Tool

A Python-based astrology calculation tool using Swiss Ephemeris for use with MCP servers and local LLMs.

## Features

- **Natal Chart Calculation**: Calculate complete birth charts with planetary positions, houses, and angles
- **Planetary Positions**: Get current positions of all planets including Mercury through Pluto
- **Aspect Calculations**: Calculate planetary aspects (conjunction, square, opposition, trine, sextile)
- **Transit Analysis**: Track transiting planets and their aspects to natal positions
  - `calculate_transits`: Single-date transit calculation
  - `scan_transits`: Date-range scanning with significance weighting and grouping
- **Lunation Scan**: Moon phases and void-of-course period detection

### Supported House Systems

- **Whole Sign only** - Each house corresponds to a full zodiac sign

## Installation

### Using a Virtual Environment (Recommended)

```bash
# Create and activate a virtual environment
python -m venv .venv
source .venv/bin/activate

# Install dependencies
pip install -r requirements.txt
```

### System-wide Installation (Not Recommended)

```bash
# Install dependencies globally
pip install -r requirements.txt
```

### Swiss Ephemeris Setup

Swiss Ephemeris requires ephemeris files for accurate calculations. Download the free ephemeris files:

1. Visit [https://www.astro.com/swisseph/](https://www.astro.com/swisseph/)
2. Download `sweph_01.zip` through `sweph_06.zip`
3. Extract to a directory (e.g., `~/ephe`)

The ephemeris files will be automatically detected or you can set the path explicitly.

## Usage

### Basic Example (Direct Library)

```python
from astrology.charts.chart import calculate_natal_chart
from datetime import datetime, timezone

# Create a chart for July 20, 2024 at 14:30 in New York
chart = calculate_natal_chart(
    birth_datetime=datetime(2024, 7, 20, 14, 30),
    latitude=40.7128,
    longitude=-74.0060
)

# Access chart data
print(f"Sun: {chart.get_planet_sign('SUN')} {chart.get_planet_degree('SUN')}°")
print(f"Ascendant: {chart.ascendant.sign_name} {chart.ascendant.degree_in_sign}°")

# Get planetary positions
for planet, position in chart.planets.items():
    print(f"{planet.name}: {position.longitude.sign_name} {position.longitude.degree_in_sign}°")

# Get house positions
for planet, house in chart.house_positions.items():
    print(f"{planet.name} is in House {house}")
```

### With Timezone Support

The library handles timezone-aware datetimes automatically. For accurate results, **include timezone information** in your datetime strings:

```python
from datetime import datetime, timezone, timedelta

# PDT (UTC-7) - California daylight saving time
birth_dt = datetime(1984, 5, 10, 20, 44, tzinfo=timezone(timedelta(hours=-7)))
chart = calculate_natal_chart(
    birth_datetime=birth_dt,
    latitude=34.0211,
    longitude=-118.3965
)

# Or use ISO format with timezone offset
chart = calculate_natal_chart(
    birth_datetime=datetime.fromisoformat("1984-05-10T20:44:00-07:00"),
    latitude=34.0211,
    longitude=-118.3965
)
```

**Note**: Without timezone info, the library assumes input is in local time and converts it to UTC. For the most accurate results, always include timezone information.

### Using with Any MCP Client

The server uses the Model Context Protocol (MCP) and can be integrated with any MCP-compatible client.

**Quick Start:**
1. Copy `mcp.json` from this project to your MCP client's configuration directory
2. Restart or reload your MCP client

**Manual Setup:**
```bash
# Activate virtual environment first
source /path/to/astrology-mcp/.venv/bin/activate

# Run the server
python -m astrology_mcp_server.main
```

The server communicates via stdio, so any MCP client that supports stdio transport can use it.

**Available tools:**
- `get_current_time` - Get the current UTC date and time
- `calculate_natal_chart` - Calculate a complete birth chart (birth_datetime with timezone recommended)
- `get_result` - Retrieve cached data by result_id (lazy loading pattern)
- `get_planet_positions` - Get current planetary positions
- `calculate_aspects` - Calculate planetary aspects between chart objects
- `calculate_transits` - Get current transits to a natal chart (single date)
- `scan_transits` - Scan transits over a date range with significance weighting and grouping
- `lunation_scan` - Scan moon phases and void-of-course periods over a date range
- `get_houses` - Get house positions for planets

**Important**: For accurate natal charts, provide birth datetime with timezone.

## MCP Caching Pattern

The server implements a lazy loading pattern for efficient LLM integration:

1. **Quick decision with preview**: `calculate_natal_chart` returns `{result_id, preview}` where preview contains key highlights (sun/moon/rising signs) for quick decisions
2. **Full data when needed**: `get_result(result_id)` fetches the full chart data
3. **Lean context for transit calculations**: `calculate_transits` and `scan_transits` can use `natal_chart_id` instead of full chart data

This pattern keeps context lean for simple decisions while allowing full data retrieval when needed.

## Project Structure

```
astrology-mcp/
├── src/
│   ├── astrology_mcp_server/
│   │   ├── __init__.py        # MCP server entry point
│   │   └── main.py            # Server main module
│   ├── astrology/
│   │   ├── __init__.py
│   │   ├── core/
│   │   │   ├── calendar.py    # Date/time handling
│   │   │   ├── ephemeris.py   # Planet positions and moon phases
│   │   │   └── aspects.py     # Aspect calculations
│   │   ├── charts/
│   │   │   └── chart.py       # Natal chart calculation
│   │   ├── transits/
│   │   │   └── transit.py     # Transit calculations
│   │   ├── progressions/
│   │   │   └── solar_arc.py   # Progression calculations (not yet implemented)
│   │   └── transit_utils.py   # Transit utility functions
│   └── serializers.py         # Data serialization utilities
├── tests/
└── mcp.json                   # MCP client configuration
```

## Development

```bash
# Ensure virtual environment is activated
source .venv/bin/activate

# Run tests
python -m pytest tests/

# Install in development mode
pip install -e .

# Run example natal chart (with your birth data)
python my_natal_chart.py

# Run all examples
python example.py
```

## Troubleshooting

### Incorrect Chart Results

If your chart shows incorrect planet signs or house positions:

1. **Check timezone handling**: Ensure your datetime has proper timezone info
   ```python
   from datetime import datetime, timezone, timedelta

   # Include timezone offset for accurate conversion to UTC
   dt = datetime.fromisoformat("1984-05-10T20:44:00-07:00")  # PDT

   chart = calculate_natal_chart(
       birth_datetime=dt,
       latitude=34.0211,
       longitude=-118.3965
   )
   ```

2. **Verify ephemeris files**: Make sure Swiss Ephemeris files are downloaded and accessible

3. **House system**: The library uses Whole Sign houses exclusively - this cannot be changed

### LM Studio Integration

LM Studio is a popular interface for running local LLMs and integrating MCP servers.

**Setup:**
1. Copy `mcp.json` from this project to your LM Studio MCP config directory (typically `~/.lmstudio/mcp.json`)
2. Restart LM Studio

**Example configuration:**
```json
{
  "mcpServers": {
    "astrology": {
      "command": "/path/to/astrology-mcp/.venv/bin/python",
      "args": [
        "-c",
        "import sys; sys.path.insert(0, '/path/to/astrology-mcp/src'); import astrology_mcp_server.main; astrology_mcp_server.main.main()"
      ]
    }
  }
}
```

**Available tools in LM Studio:**
- `get_current_time` - Get the current UTC date and time
- `calculate_natal_chart` - Calculate a complete birth chart (birth_datetime with timezone recommended)
- `get_result` - Retrieve cached data by result_id
- `get_planet_positions` - Get current planetary positions
- `calculate_aspects` - Calculate planetary aspects between chart objects
- `calculate_transits` - Get current transits to a natal chart
- `scan_transits` - Scan transits over a date range with significance weighting and grouping
- `lunation_scan` - Scan moon phases and void-of-course periods over a date range

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

**Note**: This project uses Swiss Ephemeris, which is available under a dual license
(AGPL or Commercial). See the LICENSE file for full details and attribution requirements.