Skip to main content
Glama
izmiradami

Falcı Hatun MCP Server

by izmiradami
README.md
# Falcı Hatun — Astrology & Tarot Engine

**An OKX.AI A2MCP service. It returns facts, not prose — because the agent calling it is already a language model.**

Most "AI astrology" products bolt an LLM onto a vague prompt and let it improvise the sky. This one does the opposite. Falcı Hatun computes the chart with a real ephemeris and hands the agent structured truth: every planet's longitude, sign, house and retrograde state; every aspect with its orb; every transit bisected to the exact moment it perfects; the drawn cards and their meanings.

The agent writes the reading. That split is the whole design — and it means this service needs **no LLM of its own**: no API key, no vendor bill, no rate limit, and an answer that is byte-identical every time you ask.

```
Agent  →  "birth data"  →  Falcı Hatun  →  the actual sky  →  Agent writes the reading
```

---

## Tools

| Tool | What it returns |
|---|---|
| `natal_chart` | Sun, Moon, Ascendant, Midheaven, 10 planets (sign, degree, house, retrograde), 12 house cusps, all major aspects with orbs. |
| `synastry` | Real cross-aspects between two charts, scored across four dimensions using classical significators, plus house overlays. |
| `transits` | When transiting planets form exact aspects to a person's natal placements — a dated timeline, searched from the ephemeris. |
| `sky_ahead` | Real New/Full Moons, real retrograde stations, real sign ingresses. Every date solved for. |
| `tarot_draw` | A full 78-card Turkish Rider-Waite deck, shuffled and dealt, upright/reversed, with meanings. Seedable for reproducibility. |
| `reference` | Signs, planets, aspect orbs, spreads, and every recognised birthplace. |

Chart engine: [astronomy-engine](https://github.com/cosinekitty/astronomy) (JPL-grade positions) + [luxon](https://moment.github.io/luxon/) (IANA timezone rules, so historical DST is handled rather than assumed). House system: Equal — stated in the response, because a chart that hides its house system cannot be verified.

## Bilingual by construction

This grew out of a Turkish app, and OKX.AI is a global marketplace. A tool that answers *"Kılıç Dokuzlusu: kaygı, endişe, uykusuzluk"* to an English-speaking agent has not really answered.

So nothing is replaced — everything is doubled. Every sign, planet, aspect, spread position and card meaning ships in both languages on the same response:

```json
{ "name": "Boğa",           "en": "Taurus", "element": "toprak", "elementEn": "earth" }
{ "name": "Kılıç Dokuzlusu", "nameEn": "Nine of Swords",
  "meaning":   "kaygı, endişe, uykusuzluk, kabuslar",
  "meaningEn": "anxiety, worry, sleeplessness, nightmares" }
```

The agent replies in whichever language the person used — the MCP `instructions` tell it so. All 78 cards, both orientations, are covered; a test asserts there are no gaps. Turkish stays first-class: it is the original, and it is the market this was built for.

---

## What was fake, and what is real now

This engine grew out of **Falcı Hatun**, a shipped Turkish astrology app. Porting it surfaced two features that were not doing what they claimed.

**Compatibility was a hash of the partner's name.**

```js
const seed = hash(partner.name + partner.date);
emotional:     40 + (seed % 60),
communication: 40 + ((seed >> 3) % 60),
attraction:    40 + ((seed >> 6) % 60),
```

Change one letter of the name and "emotional compatibility" moved. Neither chart was ever consulted. `synastry` now computes actual cross-aspects — Venus to Mars, Moon to Saturn, the whole grid — weighted by classical significators and orb exactness. There is a test that asserts renaming a person does **not** move the score, and that changing their birth date **does**.

**The transit timeline was six hardcoded events.**

```js
{ days: 7,  title: 'Merkür Retrosu Başlıyor' }
{ days: 14, title: 'Boğa Burcunda Dolunay' }
```

Fixed offsets from today, identical for every user. Mercury was not necessarily stationing; the Moon was not necessarily full; nobody's chart was involved. `sky_ahead` and `transits` now search the ephemeris and bisect to the exact moment — and a test checks that consecutive new moons come out one synodic month apart (~29.53 days), which a hardcoded list could never satisfy.

---

## It tells you what it doesn't know

A reading that looks authoritative and is quietly wrong is worse than no reading.

**Unknown birthplace → error, not a guess.** The original silently fell back to `{ lat: 39.0, lon: 35.0 }` — the geographic centre of Turkey — for any city it didn't recognise. The ascendant and every house cusp depend on latitude and longitude, so an unrecognised birthplace produced a confident, wrong chart. Now it raises `UnknownPlaceError` and suggests near-matches. Explicit `latitude`/`longitude` work anywhere on Earth.

**No birth time → the chart says so.** Without a time, the ascendant, the midheaven and every house placement rotate a full circle every 24 hours. Falcı Hatun still returns the chart, but the `caveats` field states plainly which parts are unusable, and the MCP `instructions` tell the calling agent not to speak about them. Transits to the Ascendant are omitted entirely rather than invented.

**A dimension with no planetary contacts scores `null`, not a number.** If two people have no Moon–Venus contact, the emotional score is absent — not filled in with something plausible.

---

## Run it

```bash
npm install
npm test        # 60 assertions
npm run dev     # http://localhost:8788/mcp
```

## Deploy

```bash
vercel --prod
```

Your MCP endpoint is `https://<your-domain>/api/mcp` — that HTTPS URL is what you register with OKX.AI.

## Call it

```bash
curl -X POST https://<your-domain>/api/mcp \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{
        "name":"natal_chart",
        "arguments":{"date":"1990-05-15","time":"09:30","place":"İzmir"}}}'
```

```json
{
  "sun":    { "name": "Boğa",  "degree": 24.17, "element": "toprak" },
  "moon":   { "name": "Oğlak", "degree": 12.4 },
  "rising": { "name": "Yengeç" },
  "planets": [
    { "name": "Merkür", "sign": { "name": "Boğa" }, "house": 10, "retrograde": true },
    { "name": "Plüton", "sign": { "name": "Akrep" }, "house": 5, "retrograde": true }
  ],
  "aspects": [
    { "from": "Güneş", "to": "Ay", "aspectTr": "üçgen", "orb": 0.16, "exactness": 0.977 }
  ],
  "houseSystem": "equal",
  "caveats": []
}
```

## Pricing

Free.

## Relationship to the Falcı Hatun app

This is a **separate, standalone service**. The mobile app is untouched — its Cloudflare Worker, its prompts and its reading flows are not used, not called, and not modified. What was carried over is the data layer (the 78-card Turkish deck, the zodiac table, the city coordinates) and the astrology mathematics, rebuilt for Node and corrected where it was wrong.

MIT.