Spaces:
Running
Running
File size: 13,861 Bytes
ee37a64 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 |
"""
Google Gemini MCP Integration
Natural language conversations about Hellenistic astrology
"""
import json
from typing import Dict, List, Optional
import os
try:
import google.generativeai as genai
GEMINI_AVAILABLE = True
except ImportError:
GEMINI_AVAILABLE = False
class GeminiMCP:
"""MCP Server for Google Gemini AI conversations about Hellenistic astrology"""
def __init__(self, api_key: Optional[str] = None):
"""
Initialize Gemini MCP server
Args:
api_key: Google AI API key (or set GOOGLE_API_KEY environment variable)
"""
self.api_key = api_key or os.getenv("GOOGLE_API_KEY")
self.model_name = "gemini-pro"
self.conversation_history = []
if GEMINI_AVAILABLE and self.api_key:
genai.configure(api_key=self.api_key)
self.model = genai.GenerativeModel(self.model_name)
self.chat = None
self.is_configured = True
else:
self.model = None
self.chat = None
self.is_configured = False
# Hellenistic astrology system prompt
self.system_prompt = """You are an expert in Hellenistic astrology (1st-7th century CE).
You specialize in:
- Essential dignities (domicile, exaltation, triplicity, bound, decan)
- Sect (day/night charts and benefic/malefic teams)
- Whole Sign houses (traditional house system)
- Traditional aspects with orbs
- Lots/Parts (Fortune, Spirit, Eros, etc.)
- Time-lord techniques (profections, zodiacal releasing, firdaria)
- Classical texts (Vettius Valens, Ptolemy, Dorotheus, Paulus Alexandrinus)
**Teaching Style:**
- Explain concepts clearly for beginners
- Reference primary sources when relevant
- Distinguish traditional vs. modern techniques
- Use examples from classical texts
- Be precise about technical terminology
**Always:**
- Cite sources (ancient or modern)
- Explain "why" behind techniques, not just "what"
- Connect theory to practical interpretation
- Note when techniques vary between authors
- Encourage further study of primary texts
**Never:**
- Make predictions without chart data
- Mix modern psychological astrology with traditional
- Oversimplify complex techniques
- Claim certainty about contested interpretations"""
def ask_question(
self,
question: str,
include_sources: bool = True
) -> Dict:
"""
Ask a question about Hellenistic astrology
Args:
question: User's question
include_sources: Whether to request source citations
Returns:
AI response with explanation and sources
"""
if not self.is_configured:
return {
"error": "Gemini not configured",
"message": "Please set GOOGLE_API_KEY environment variable or provide API key",
"fallback": self._get_fallback_response(question)
}
try:
# Start new chat if needed
if not self.chat:
self.chat = self.model.start_chat(history=[])
# Send system prompt as first message
self.chat.send_message(self.system_prompt)
# Add instruction for sources if requested
if include_sources:
full_question = f"{question}\n\n(Please include relevant classical sources in your answer.)"
else:
full_question = question
# Send question
response = self.chat.send_message(full_question)
return {
"question": question,
"answer": response.text,
"model": self.model_name,
"conversation_turn": len(self.conversation_history) + 1,
"source": "Google Gemini via HERMES MCP"
}
except Exception as e:
return {
"error": f"Gemini API error: {str(e)}",
"question": question,
"fallback": self._get_fallback_response(question)
}
def _get_fallback_response(self, question: str) -> str:
"""
Provide fallback responses when Gemini unavailable
Returns basic information about common topics
"""
fallback_db = {
"dignit": """**Essential Dignities** measure planetary strength by zodiacal position.
The five levels are:
1. **Domicile** (+5): Planet in its home sign (e.g., Sun in Leo)
2. **Exaltation** (+4): Planet in its exaltation (e.g., Sun in Aries)
3. **Triplicity** (+3): Planet ruling the element
4. **Bound/Term** (+2): Planet ruling degree ranges within signs
5. **Decan/Face** (+1): Planet ruling 10-degree sections
**Debilities** are opposites:
- **Detriment** (-5): Opposite of domicile (e.g., Sun in Aquarius)
- **Fall** (-4): Opposite of exaltation (e.g., Sun in Libra)
*Source: Ptolemy's Tetrabiblos, Vettius Valens*""",
"sect": """**Sect** divides charts into day and night teams.
**Day Chart** (Sun above horizon):
- Sun, Jupiter, Saturn = Day team (stronger)
- Moon, Venus, Mars = Night team (weaker)
- Jupiter = benefic, Saturn = malefic (but of the day team)
**Night Chart** (Sun below horizon):
- Moon, Venus, Mars = Night team (stronger)
- Sun, Jupiter, Saturn = Day team (weaker)
- Venus = benefic, Mars = malefic (but of the night team)
Planets in-sect function better than out-of-sect planets.
*Source: Vettius Valens, Anthology Book II*""",
"profection": """**Annual Profections** move the Ascendant forward one house per year.
**How it works:**
1. Start at Ascendant (age 0-1)
2. Move to 2nd house (age 1-2)
3. Continue advancing one house per year
4. At age 12, return to Ascendant (12-year cycle)
The **profected house** shows the year's themes.
The **ruler** of that house becomes **Lord of the Year**.
Example: Age 35 profects to the 12th house (35 % 12 = 11, +1 = 12th).
*Source: Vettius Valens, Paulus Alexandrinus*""",
"whole sign": """**Whole Sign Houses** assign entire signs to houses.
**How it works:**
1. Ascendant sign = entire 1st house (0-30°)
2. Next sign = entire 2nd house
3. Continue through all 12 signs
This is the **original Hellenistic house system** (1st-7th century).
**Benefits:**
- Simple and clear
- Each house is exactly 30°
- Easy to determine house rulers
- Used by Vettius Valens, Dorotheus
Modern systems (Placidus, Koch) came later (16th-18th century).
*Source: Chris Brennan, Hellenistic Astrology (2017)*"""
}
# Check for keywords
question_lower = question.lower()
for keyword, response in fallback_db.items():
if keyword in question_lower:
return response
# Default response
return """**API Key Required**
For AI-powered conversations, set your Google AI API key:
```python
export GOOGLE_API_KEY="your-key-here"
```
Get a free API key at: https://makersuite.google.com/app/apikey
**Meanwhile, try these resources:**
- Chris Brennan: "Hellenistic Astrology: The Study of Fate and Fortune" (2017)
- Vettius Valens: "Anthology" (Project Hindsight translation)
- Demetra George: "Ancient Astrology in Theory and Practice" (2019)
**Or ask specific questions like:**
- "What are essential dignities?"
- "How does sect work?"
- "What are annual profections?"
- "What are Whole Sign houses?" """
def explain_technique(
self,
technique: str,
level: str = "beginner"
) -> Dict:
"""
Get detailed explanation of a traditional technique
Args:
technique: Name of technique (dignities, profections, lots, etc.)
level: Explanation level (beginner, intermediate, advanced)
Returns:
Structured explanation tailored to level
"""
levels_prompt = {
"beginner": "Explain this as if teaching someone new to astrology. Use simple language and clear examples.",
"intermediate": "Provide a comprehensive explanation with examples and source citations.",
"advanced": "Give an in-depth technical explanation including variant methods across classical authors."
}
question = f"""Please explain the technique of {technique} in Hellenistic astrology.
Level: {levels_prompt.get(level, levels_prompt['beginner'])}
Include:
1. What it is and why it's used
2. How to calculate or apply it
3. An example
4. Classical sources
5. Common mistakes to avoid"""
return self.ask_question(question, include_sources=True)
def interpret_placement(
self,
planet: str,
sign: str,
house: int,
aspects: Optional[List[str]] = None,
is_day_chart: bool = True
) -> Dict:
"""
Get AI interpretation of a planetary placement
Args:
planet: Planet name
sign: Zodiac sign
house: House number (1-12)
aspects: List of aspects (e.g., ["square Mars", "trine Jupiter"])
is_day_chart: Whether it's a day chart (for sect analysis)
Returns:
Detailed interpretation using Hellenistic principles
"""
aspect_text = f"\nAspects: {', '.join(aspects)}" if aspects else ""
chart_type = "day chart" if is_day_chart else "night chart"
question = f"""Interpret this planetary placement using Hellenistic astrology:
**Planet:** {planet}
**Sign:** {sign}
**House:** {house}
**Chart Type:** {chart_type}{aspect_text}
Please analyze:
1. Essential dignity (domicile, exaltation, detriment, fall)
2. Sect condition (in-sect or out-of-sect)
3. House signification
4. Aspects and their influence
5. Overall interpretation
Use traditional Hellenistic principles and cite classical sources where relevant."""
return self.ask_question(question, include_sources=True)
def compare_techniques(
self,
technique1: str,
technique2: str
) -> Dict:
"""
Compare two astrological techniques
Args:
technique1: First technique
technique2: Second technique
Returns:
Comparison with similarities, differences, and when to use each
"""
question = f"""Compare these two techniques in Hellenistic astrology:
1. {technique1}
2. {technique2}
Please explain:
- What each technique does
- Similarities and differences
- Historical origins
- When to use each one
- How they complement each other
Include classical sources where relevant."""
return self.ask_question(question, include_sources=True)
def reset_conversation(self):
"""Reset conversation history and start fresh"""
self.conversation_history = []
if self.chat:
self.chat = None
return {"status": "Conversation reset", "ready": True}
def get_mcp_tools() -> List[Dict]:
"""Return list of available Gemini MCP tools"""
return [
{
"name": "ask_question",
"description": "Ask any question about Hellenistic astrology",
"parameters": {
"question": "string (your question)",
"include_sources": "boolean (optional, default True)"
},
"returns": "AI-generated answer with classical sources"
},
{
"name": "explain_technique",
"description": "Get detailed explanation of a traditional technique",
"parameters": {
"technique": "string (dignities, profections, lots, etc.)",
"level": "string (beginner, intermediate, advanced)"
},
"returns": "Structured explanation tailored to experience level"
},
{
"name": "interpret_placement",
"description": "Get interpretation of a planetary placement",
"parameters": {
"planet": "string",
"sign": "string",
"house": "integer (1-12)",
"aspects": "list of strings (optional)",
"is_day_chart": "boolean (optional, default True)"
},
"returns": "Hellenistic interpretation with sect and dignity analysis"
},
{
"name": "compare_techniques",
"description": "Compare two astrological techniques",
"parameters": {
"technique1": "string",
"technique2": "string"
},
"returns": "Comparison with when to use each"
},
{
"name": "reset_conversation",
"description": "Reset conversation history",
"parameters": {},
"returns": "Confirmation of reset"
}
]
# Main entry point
if __name__ == "__main__":
import sys
if len(sys.argv) > 1 and sys.argv[1] == "tools":
print(json.dumps(get_mcp_tools(), indent=2))
else:
print("=" * 70)
print("Google Gemini MCP Server")
print("Natural Language Hellenistic Astrology Conversations")
print("=" * 70)
print("\nAvailable Tools:")
print(json.dumps(get_mcp_tools(), indent=2))
# Test example
print("\n" + "=" * 70)
print("TEST: Ask Question (Fallback Mode)")
print("=" * 70)
server = GeminiMCP()
result = server.ask_question("What are essential dignities?")
print(json.dumps(result, indent=2))
if not GEMINI_AVAILABLE:
print("\n⚠️ Note: google-generativeai package not installed")
print(" Install with: pip install google-generativeai")
if not server.api_key:
print("\n⚠️ Note: GOOGLE_API_KEY not set")
print(" Get free API key: https://makersuite.google.com/app/apikey")
print(" Set with: export GOOGLE_API_KEY='your-key'")
|