Osiem systemów ezoterycznych. Jedno API. Gotowe dla AI.
REST pod /v1/* i serwer MCP pod /mcp — dwa interfejsy nad tym samym
rdzeniem eldermind-core,
w jednym procesie. Zero duplikacji logiki: cache, limit współbieżności, kredyty
i obsługa błędów istnieją w jednym egzemplarzu.
Astrologia zachodnia · astrologia wedyjska (Jyotish) · Human Design · Gene Keys · Matryca Losu · BaZi (Cztery Filary) · numerologia pitagorejska · karta drakoniczna. Plus Animal Design dla psów, kotów i koni.
Wszystko lokalnie na Swiss Ephemeris. Żadnego zewnętrznego API astrologicznego w torze wykonania.
Determinizm. Każde obliczenie jest czystą funkcją swoich argumentów. Przypnij
reference_date, a te same dane wejściowe zwrócą te same bajty bezterminowo.
29 testów złotych wywala build, jeśli ruszy się choć jedna liczba.
Poziomy szczegółowości. Pełny profil to ~30 KB, czyli ~7 700 tokenów — jedno
wywołanie narzędzia zjadłoby kontekst modelu, zanim ten zdąży cokolwiek powiedzieć.
detail: "summary" daje ~2 KB samych wniosków.
| Poziom | Rozmiar | Zawartość |
|---|---|---|
summary |
~2,2 KB | tylko wnioski — domyślny dla MCP |
standard |
~18 KB | wszystkie pozycje, bez tablic historycznych — domyślny dla REST |
full |
~30 KB | + oś Dasha (100 lat), pełne Da Yun, aktywacje HD |
Częściowe powodzenie. W bundlu jeden system, który zawiedzie, nie kosztuje Cię
pozostałych siedmiu — błąd ląduje w meta.errors[], reszta wraca normalnie.
Urodzony w Tromsø dostaje 7 z 8 systemów zamiast błędu (Placidus jest za kołem
podbiegunowym matematycznie nieokreślony).
Rdzeń jest osobnym repozytorium i nie ma go na PyPI, więc trzeba go
sklonować obok i zainstalować pierwszy — w odwrotnej kolejności pip próbuje
pobrać eldermind-core z sieci i przerywa instalację.
git clone https://github.com/ElderMindAI/eldermind-core.git
git clone https://github.com/ElderMindAI/eldermind-astro-api.git
cd eldermind-astro-api
python -m venv .venv && . .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -e ../eldermind-core
pip install -e ".[dev,mcp]"
cp .env.example .env.local
uvicorn app.main:app --port 8010 --reloadWymagany Python 3.11+. Ekstras [mcp] nie jest opcjonalny w praktyce: bez niego
serwis wstaje, odpowiada 200 na /health i ma komplet tras REST — ale nie ma
/mcp, czyli tego, na czym stoi produkt.
Dokumentacja interaktywna: http://127.0.0.1:8010/docs
curl -X POST http://127.0.0.1:8010/v1/profile/complete \
-H "Authorization: Bearer sk_test_development" \
-H "Content-Type: application/json" \
-d '{"subject":{"birth_date":"1993-09-01","birth_time":"14:30",
"latitude":52.2297,"longitude":21.0122,"timezone":"Europe/Warsaw",
"gender":"male"},"detail":"summary"}'Lokalnie, przez stdio: python run_mcp_stdio.py.
Użytkownik podaje wyłącznie URL https://api.eldermind.io/mcp i przechodzi
logowanie. Reszta jest odkrywana automatycznie:
| Krok | Standard | Endpoint |
|---|---|---|
| 401 wskazuje metadane | RFC 9728 | WWW-Authenticate: ... resource_metadata="..." |
| Metadane zasobu | RFC 9728 | /.well-known/oauth-protected-resource/mcp |
| Metadane serwera autoryzacji | RFC 8414 | /.well-known/oauth-authorization-server |
| Rejestracja klienta | RFC 7591 | POST /register |
| Autoryzacja + PKCE | OAuth 2.1 | GET /authorize → ekran zgody → POST /token |
| Odwołanie | RFC 7009 | POST /revoke |
Token OAuth to delegacja istniejącego konta, nie nowe konto. Ekran zgody
prosi raz o klucz API; wydany token nosi jego identyfikator. Dzięki temu
uprawnienia, kredyty i limity działają identycznie niezależnie od tego, czy
żądanie przyszło z Bearer sk_live_..., czy z tokenu OAuth — reguły żyją
w jednym miejscu.
Zakresy zawężają, nigdy nie poszerzają. Efektywny dostęp to część wspólna
uprawnień planu i zakresów tokenu. Zgoda na system:bazi nie da dostępu do
wedyjskiej, a plan obejmujący wszystko i tak nie przekroczy tego, na co
użytkownik się zgodził. Katalog zakresów: GET /oauth/scopes.
Access token żyje godzinę, refresh 30 dni i rotuje przy każdym użyciu — skradziony działa tylko do najbliższego odświeżenia przez prawdziwego klienta. Kod autoryzacyjny jest jednorazowy. Odwołanie klucza natychmiast unieważnia wszystkie wydane na niego tokeny.
| Narzędzie | Kredyty |
|---|---|
resolve_birth_data — nazwa miejsca → współrzędne i strefa |
0 |
get_planetary_positions — niebo o dowolnej porze, bez danych urodzeniowych |
1 |
get_western_chart · get_human_design · get_gene_keys · get_matrix_of_destiny · get_bazi · get_numerology · get_draconic_chart |
1 |
get_vedic_chart · get_animal_design |
2 |
get_complete_profile — wszystkie 8 systemów naraz |
6 |
lookup_knowledge — opis bramy, kanału, linii, Gene Key |
1 |
get_usage — stan kredytów |
0 |
Bundle kosztuje 6 zamiast 9 — rabat jest narzędziem projektowym, nie promocją: steruje zachowaniem modelu ceną, żeby wybierał jedno wywołanie zamiast ośmiu.
Zasoby: eldermind://systems, eldermind://methodology
Prompty: natal_reading, timing_advice, compatibility_brief
resolve_birth_datajest osobnym narzędziem, bo model ma „Kraków", nigdy 52.23/21.01. Bez tego kroku każdy przepływ wykłada się na pierwszym pytaniu.- Nazwy, nie kody.
"Manifesting Generator", nie"type_2". Model ma to rozumieć bez tablicy odwzorowań. - Błędy niosą instrukcję. Komunikat przy wyczerpanych kredytach mówi wprost: „poinformuj użytkownika i wskaż stronę cennika — nie wymyślaj wyniku". Model, który dostanie sam kod błędu, dopowie sobie kartę.
- Ostrzeżenia zamiast fałszywej precyzji. Brak godziny urodzenia naprawdę
psuje Ascendent, domy i Księżyc —
warningsmówi to modelowi wprost.
Każda awaria wygląda tak samo:
{"error": {
"code": "AMBIGUOUS_LOCAL_TIME",
"message": "Local time 02:30:00 on 1993-03-28 does not exist in Europe/Warsaw (daylight-saving gap).",
"field": "birth_time",
"request_id": "req_01JD8X...",
"docs_url": "https://eldermind.io/api/docs/errors#ambiguous-local-time"
}}INVALID_API_KEY · INSUFFICIENT_CREDITS · SYSTEM_NOT_ENTITLED ·
INVALID_TIMEZONE · AMBIGUOUS_LOCAL_TIME · DATE_OUT_OF_RANGE ·
HOUSE_SYSTEM_UNAVAILABLE · GEOCODING_FAILED · RATE_LIMITED ·
SERVICE_BUSY · CALCULATION_ERROR
- Bez godziny urodzenia przyjmujemy 12:00; Ascendent, domy, filar godziny
i Księżyc są niewiarygodne. Zawsze oflagowane w
warnings. - Za kołem podbiegunowym Placidus jest nieokreślony. Karta zachodnia zwraca typowany błąd z podpowiedzią; wedyjska liczy się dalej (Whole Sign działa wszędzie).
- Przejścia czasu letniego — godzina z luki wiosennej nigdy nie istniała, z nakładki jesiennej wystąpiła dwa razy. Odrzucamy obie zamiast zgadywać.
- Zakres dat 1800–2200.
Klucze: HMAC-SHA256 z pepperem, plaintext nigdy nie trafia do bazy —
przechowujemy hash i krótki prefiks (sk_live_a1b2…), po którym użytkownik
rozpoznaje własne klucze w panelu. Pepper żyje w środowisku, nie w bazie, więc
sam wyciek bazy nie wystarczy do podrobienia klucza — i, co ciekawsze, nie
wystarczy też zapis do bazy. Hashe sprzed tej zmiany zaczynają się od
$argon2id$ i są nadal akceptowane przy weryfikacji.
Klucz cache'u to SHA-256 wejść — nie da się z niego odtworzyć daty urodzenia.
usage_events zawiera wyłącznie metryki; data urodzenia i imię nigdy nie
trafiają do zapisu ani do logów. Test tego pilnuje.
pytest # 281 testów
pytest ../eldermind-core # 122 testy, w tym 29 złotychKod jest udostępniony do wglądu, nie open source. Wolno go czytać, studiować
i oceniać; użycie w produkcie lub usłudze wymaga pisemnej zgody. Pełne warunki:
LICENSE.