@lhk714/bazi-mcp
by listen-hai
README.md
# Bazi MCP (`@lhk714/bazi-mcp`)
[](https://www.npmjs.com/package/@lhk714/bazi-mcp)
[](LICENSE)
[](https://github.com/listen-hai/bazi-mcp/actions/workflows/ci.yml)
[]()
[]()
> Deterministic, high-precision Four Pillars of Destiny (八字排盘) Model Context Protocol (MCP) server powered by a physical dual-axis astronomical time engine and global geographic database (7,329 cities across 227 countries).
[中文文档 (Chinese)](README_zh.md) | [English](README.md)
---
## 🌟 Overview
`@lhk714/bazi-mcp` provides a production-grade, offline-first MCP server for Large Language Models (Claude, Cursor, Antigravity, ChatGPT, DeepSeek) to perform rigorous Chinese Four Pillars of Destiny (八字) calculations for anyone, anywhere on Earth, across 1800–2100.
It is published on the NPM registry and can be run instantly without manual installation or local compilation.
```
Birth Wall Clock Time + IANA Timezone (e.g. 1990-06-15 20:00 America/Los_Angeles)
│
┌─────────────┴─────────────┐
▼ ▼
【Axis A: UTC Instant】 【Axis B: Local True Solar Time】
UTC: 1990-06-16 03:00:00Z Wall + Longitude + Meeus EoT - DST
Beijing: 1990-06-16 11:00 Local Solar: 1990-06-15 18:49
│ │
├──────────────┐ ├──────────────┐
▼ ▼ ▼ ▼
【Year Pillar】 【Month Pillar】 【Day Pillar】 【Hour Pillar】
庚午 壬午 辛亥 丁酉
│
▼
【Da Yun (起运)】
```
---
## 🔮 What this server will not tell you
**It calculates; it does not infer.** 身强/身弱, 喜用神 and 格局 are weighings, and no
source supplies the weights they need — every published figure either contradicts
the next or comes from closed software. A scored verdict here would rest on
numbers invented in this repository, however carefully the method were named.
v3.1.0 shipped one; v4.0.0 removed it.
What you get instead is `strengthFactors`, a zero-weight ledger: 月令 relation and
旺相休囚死, per-branch roots with their qi level and any 禄/刃/长生/墓库根 tag,
and stem-support direction.
Every entry is a table lookup. Weigh them with your own school's rules, or with a
命理 knowledge base — the facts are all here, and they are the part that can be
got right.
Every table that sits on a school dispute is a named input, and
`strengthFactors.conventions` echoes back the one in force, the ones not used,
and the output fields that would change:
| parameter | default | alternatives |
|---|---|---|
| `twelveStageSchool` | 阳顺阴逆 (渊海子平) | `yin_follows_yang` — 阴阳同生同死 (滴天髓) |
| `monthOrderSchool` | 月支本气为令 | `earth_rules_final_18_days` — 土旺四季十八日 |
| `bladeSchool` | 阳刃 only | `yin_at_diwang`, `yin_at_guandai` |
`monthOrderSchool: "earth_rules_final_18_days"` gives 土 the final 18 days before
the next 立 and leaves the days before them with the closing season (辰木 未火
戌金 丑水). Only 辰戌丑未 months can move; the other eight have the season's
element as their main qi already. The distance it turns on ships with the
result as `monthOrder.daysToNextJie`, and the element it resolved to as
`monthOrder.rulingElement`, so the verdict is reproducible from the output.
阴刃 gets no default. Three readings are in print — 帝旺 (乙寅 丁巳 己巳 辛申
癸亥), 冠带/禄前一位 (乙辰 丁未 己未 辛戌 癸丑), and no 阴刃 at all — and nothing
here breaks the tie, so the caller names one or gets 阳刃 alone.
For a yin day master the 十二长生 fork moves every branch: 辛 in 巳 is 死 under the
default 渊海子平 convention, 长生 under 滴天髓's 阴阳同生同死. Pass
`twelveStageSchool: "yin_follows_yang"` to take the second one; the school in force
is echoed back in `conventions.twelveStage`. Yang day masters are identical under
both. 禄 and 刃 are read from the 十干禄 and 阳刃 tables and do not move with the
fork — only 长生 does.
Absent entirely when the birth hour is unknown.
## 🚀 Quickstart: Run via NPM
You can run `@lhk714/bazi-mcp` directly from NPM using **Bun** or **Node.js (NPX)** with zero local repository setup.
### Option 1: Instant execution with Bun (`bunx`)
```bash
bunx @lhk714/bazi-mcp
```
### Option 2: Instant execution with Node.js (`npx`)
```bash
npx -y @lhk714/bazi-mcp@latest
```
### Option 3: Global Installation
```bash
# Install globally via Bun
bun add -g @lhk714/bazi-mcp
# Or install globally via NPM
npm install -g @lhk714/bazi-mcp@latest
# Then run anywhere:
bazi-mcp
```
---
## ⚙️ MCP Client Configuration
Add `@lhk714/bazi-mcp` to your MCP client config (e.g. Claude Desktop, Cursor, Cline, Roo Code, Antigravity):
#### Using Bun (`bunx`):
```json
{
"mcpServers": {
"bazi": {
"command": "bunx",
"args": ["@lhk714/bazi-mcp@latest"]
}
}
}
```
#### Using Node.js (`npx`):
```json
{
"mcpServers": {
"bazi": {
"command": "npx",
"args": ["-y", "@lhk714/bazi-mcp@latest"]
}
}
}
```
---
## 🛠️ MCP Tools Reference
### 1. `calculate_bazi`
Calculates Four Pillars, Day Master, Da Yun (Major Luck Cycles labeled with nominal age 虚岁), Stem & Branch Interactions (天干五合、地支刑冲合会), and Diagnostic Metadata.
| Parameter | Type | Required | Description |
|---|---|---|---|
| `place` | string | Optional | City name in English (e.g. `"Beijing"`, `"New York"`, `"Tacoma, WA"`, `"Lagos"`, `"London, United Kingdom"`). AI agents automatically translate any user language. |
| `longitude` | number | Optional | Birth longitude in degrees (East positive, e.g. `102.8329` or `-122.4443`). *Note for Date Line locations (e.g. Chatham Islands): express longitude in [-180, 180] (e.g. `-176.55` in `UTC+12:45`), normalized against the standard time meridian.* *For births near the antimeridian, the underlying true-solar-time correction wraps by 360°, so the day pillar follows the **civil** date at the birth location even though the sub-solar date is a full day earlier — this is a deliberate convention, not a bug.* |
| `timezone` | string | Optional | IANA timezone identifier (e.g. `"Asia/Shanghai"`, `"America/Los_Angeles"`) |
| `solarDate` | object | Optional* | Solar birth date `{ "year": 1990, "month": 1, "day": 1 }` (supported: 1800–2100) |
| `lunarDate` | object | Optional* | Lunar birth date `{ "year": 1989, "month": 12, "day": 5, "isLeapMonth": false }` (supported: 1800–2100) |
| `lunarDateFrame` | string | Optional | `"local"` (default) or `"beijing"` |
| `clockTime` | object | Optional** | Local wall clock time `{ "hour": 11, "minute": 27 }` |
| `shichen` | string | Optional** | Traditional Chinese two-hour branch (`'子'` to `'亥'`) |
| `timeUnknown` | boolean | Optional** | Set `true` for a 3-pillar chart. The remaining three pillars are **not** silently computed from a substituted noon — see [Unknown birth time](#unknown-birth-time) |
| `dstFold` | number | Optional | `0` (DST) or `1` (Standard) for ambiguous fall-back overlap hours |
| `gender` | string | **Required** | `"male"` (乾造) or `"female"` (坤造) |
| `sect` | number | Optional | `2` (default, 23:00 Zi-hour rollover / 子初换日, self-consistent with rat-chasing cycle 五鼠遁) or `1` (00:00 midnight day rollover / 子正换日) |
| `solarTime` | string | Optional | Solar time correction mode: `"true"` (default, longitude correction + equation of time), `"mean"` (longitude correction only, 地方平太阳时), or `"off"` (neither, wall clock as given) |
| `trueSolar` | boolean | Optional, deprecated | Use `solarTime` instead (`true` → `"true"`, `false` → `"off"`). Supplying both is rejected if they disagree. |
*\* Provide either `solarDate` or `lunarDate`.*
*\*\* Provide either `clockTime`, `shichen`, or `timeUnknown: true`.*
`diagnostics.locationSource` reports whether the location was `"resolved"` from the global city database, `"caller_supplied"` via explicit coordinates, or `"mixed"` (place coordinates paired with a caller-supplied custom timezone).
---
### 2. `lookup_location`
Resolves city names to coordinates, administrative regions, and official IANA timezone identifiers across 7,329 global cities in 227 countries.
**Ambiguous names are refused, never guessed** — including same-name cities that share a timezone. Columbus OH and Columbus GA are both `America/New_York` but sit 2° of longitude apart: 8 minutes of true solar time, enough to cross a 時辰 boundary. A refusal returns `{ code, message, matched, candidates }`, where `matched` is the true hit count so a capped list never reads as exhaustive, and candidates carry identifying fields only (no population — that is a ranking prior, not an identifier).
## Unknown birth time
`timeUnknown: true` nulls the hour pillar, but the other three and the 大運 sequence are **not** derived from a substituted time.
- The year, month and day pillars are evaluated at both ends of the local day. Where they agree, they are reported plainly. Where a solar term falls inside the day and they disagree, both land in `diagnostics.pillarCandidates` with a warning — no side is silently chosen.
- The 早子時 hour (23:00–24:00) rolls the day pillar on **every** date, not just special ones. That uncertainty is asymmetric — 23 of 24 hours give one value — so it is reported asymmetrically: `pillars.day` holds the majority value and `diagnostics.dayPillarAlternative` names the other with its window. A 50/50 candidate pair would misstate how much is actually unknown.
- `daYun.startDate` becomes a date range. Measured on 2024-02-04 in Beijing, the 起運 date swings across three months over one unknown day; a to-the-second answer there is a fabrication.
| Parameter | Type | Required | Description |
|---|---|---|---|
| `query` | string | **Required** | City query string in English (e.g. `"Tokyo"`, `"Seattle"`, `"Paris"`, `"Kunming"`) |
---
## 🧪 Verification & Benchmark Matrix
`@lhk714/bazi-mcp` is verified against 117 rigorous test cases (100% passing):
1. **Astro-Databank Rodden Rating AA Hospital Birth Certificates**:
- **Donald Trump**: `1946-06-14 10:54 EDT` (New York, NY) ➔ `丙戌 甲午 己未 己巳`
- **Barack Obama**: `1961-08-04 19:24 HST` (Honolulu, HI) ➔ `辛丑 乙未 己巳 癸酉`
- **Bill Gates**: `1955-10-28 22:00 PST` (Seattle, WA) ➔ `乙未 丙戌 壬戌 辛亥`
- **Steve Jobs**: `1955-02-24 19:15 PST` (San Francisco, CA) ➔ `乙未 戊寅 丙辰 丁酉` *(True Solar correction shifts 19:15 to 18:52 酉 hour)*
- **Albert Einstein**: `1879-03-14 11:30` (Ulm, Germany) ➔ `己卯 丁卯 丙申 甲午`
2. **Official Historical Archives & Canonical Metaphysics Records**:
- **Chiang Kai-shek**: `1887-10-31 12:00` (Zhejiang Fenghua - *Qian Li Ming Gao*) ➔ `丁亥 庚戌 己巳 庚午`
- **Mao Zedong**: `1893-12-26 辰时` (Hunan Shaoshan) ➔ `癸巳 甲子 丁酉 甲辰`
- **Zhou Enlai**: `1898-03-05 卯时` (Jiangsu Huaian) ➔ `戊戌 甲寅 丁卯 癸卯`
- **Deng Xiaoping**: `1904-08-22 申时` (Sichuan Guangan) ➔ `甲辰 壬申 戊子 庚申`
- **Liang Qichao**: `1873-02-23 丑时` (Guangdong Xinhui) ➔ `癸酉 甲寅 丙午 己丑`
3. **Global Multi-Region Suite (28 regions across 6 continents)**:
- China (Kashgar extreme west, Harbin extreme east, Lhasa high-altitude, Sanya tropical, Hong Kong, Taipei).
- Americas (New York, Los Angeles, Chicago, Phoenix no-DST, St. John's 30-min timezone, São Paulo, Buenos Aires).
- Europe & Eurasia (London GMT/BST, Paris, Moscow, Vladivostok, Reykjavik UTC+0).
- Asia & Middle East (Tokyo, Seoul, Singapore, New Delhi / Mumbai UTC+5:30, Dubai).
- Oceania & Southern Hemisphere (Sydney reversed DST, Perth, Auckland).
- Africa (Johannesburg, Cairo).
---
## 🔄 CI/CD & Automated NPM Publishing
The repository is equipped with automated GitHub Actions:
- **Continuous Integration (`ci.yml`)**: Runs tests and builds on every push/PR to `main`.
- **Automated NPM Release (`publish.yml`)**: Automatically tests, builds, and publishes `@lhk714/bazi-mcp` to NPM whenever a new release or tag (e.g. `v1.0.0`) is created.
---
## 📜 License
[MIT License](LICENSE) © 2026 Wesley Liu
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues