aamanlamba commited on
Commit
ee37a64
·
verified ·
1 Parent(s): 9e59094

Add 3 new MCP server integrations: Local HERMES, Astro.com, Gemini AI

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