-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
142 lines (122 loc) · 5.26 KB
/
Copy pathmain.py
File metadata and controls
142 lines (122 loc) · 5.26 KB
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
from mcp.server.fastmcp import FastMCP, Context
import httpx
import asyncio
from typing import Dict, List
from datetime import datetime
# Initialize the MCP server
mcp = FastMCP("CryptoFearGreed", dependencies=["httpx"])
# API endpoint for Crypto Fear & Greed Index
API_URL = "https://api.alternative.me/fng/"
# Resource to get current Fear & Greed Index
@mcp.resource("fng://current")
async def get_current_fng() -> str:
"""Get the current Crypto Fear & Greed Index"""
try:
async with httpx.AsyncClient() as client:
response = await client.get(API_URL, params={"limit": 1})
response.raise_for_status()
data = response.json()["data"][0]
timestamp = datetime.fromtimestamp(int(data["timestamp"]))
return (
f"Crypto Fear & Greed Index (as of {timestamp} UTC):\n"
f"Value: {data['value']}\n"
f"Classification: {data['value_classification']}"
)
except httpx.HTTPStatusError as e:
return f"Error fetching current FNG: {str(e)}"
except Exception as e:
return f"Unexpected error: {str(e)}"
# Resource to get historical Fear & Greed Index
@mcp.resource("fng://history/{days}")
async def get_historical_fng(days: str) -> str:
"""Get historical Crypto Fear & Greed Index for specified number of days"""
try:
days_int = int(days)
if days_int <= 0:
raise ValueError("Days must be a positive integer")
async with httpx.AsyncClient() as client:
response = await client.get(API_URL, params={"limit": days_int})
response.raise_for_status()
data = response.json()["data"]
result = ["Historical Crypto Fear & Greed Index:"]
for entry in reversed(data): # Latest first
timestamp = datetime.fromtimestamp(int(entry["timestamp"]))
result.append(
f"{timestamp} UTC: {entry['value']} ({entry['value_classification']})"
)
return "\n".join(result)
except ValueError as e:
return f"Error: {str(e)}"
except httpx.HTTPStatusError as e:
return f"Error fetching historical FNG: {str(e)}"
except Exception as e:
return f"Unexpected error: {str(e)}"
# Tool version of get_current_fng
@mcp.tool()
async def get_current_fng_tool(ctx: Context) -> str:
"""Get the current Crypto Fear & Greed Index as a tool."""
ctx.info("Fetching current Fear & Greed Index")
return await get_current_fng()
# Tool version of get_historical_fng
@mcp.tool()
async def get_historical_fng_tool(days: int, ctx: Context) -> str:
"""
Get historical Fear & Greed Index for specified number of days as a tool.
Parameters:
days (int): Number of days to retrieve (must be a positive integer).
Returns:
str: Historical Fear & Greed Index values for the specified period.
"""
ctx.info(f"Fetching historical Fear & Greed Index for {days} days")
return await get_historical_fng(str(days))
# Tool to analyze trends in the Fear & Greed Index
@mcp.tool()
async def analyze_fng_trend(days: int, ctx: Context) -> str:
"""
Analyze trends in Crypto Fear & Greed Index over specified days.
Parameters:
days (int): Number of days to analyze (must be a positive integer).
Returns:
str: A string containing the analysis results, including latest value,
average value, trend direction, and number of data points analyzed.
"""
if days <= 0:
return "Error: Days must be a positive integer"
ctx.info(f"Fetching {days} days of FNG data")
try:
async with httpx.AsyncClient() as client:
response = await client.get(API_URL, params={"limit": days})
response.raise_for_status()
data = response.json()["data"]
if not data:
return "Error: No data available"
values = [int(entry["value"]) for entry in data]
total_entries = len(values)
# Calculate statistics
avg = sum(values) / total_entries
trend = "rising" if values[0] > values[-1] else "falling" if values[0] < values[-1] else "stable"
latest = data[0] # Most recent entry
result = [
f"Fear & Greed Index Analysis ({days} days):",
f"Latest Value: {latest['value']} ({latest['value_classification']}) "
f"at {datetime.fromtimestamp(int(latest['timestamp']))} UTC",
f"Average Value: {avg:.1f}",
f"Trend: {trend}",
f"Data points analyzed: {total_entries}"
]
return "\n".join(result)
except httpx.HTTPStatusError as e:
return f"Error fetching data: {str(e)}"
except Exception as e:
return f"Unexpected error: {str(e)}"
# Prompt for interpreting the index
@mcp.prompt()
def interpret_fng(value: str) -> str:
"""Generate an interpretation of a Fear & Greed Index value"""
return (
f"Please interpret this Crypto Fear & Greed Index value and explain what it means "
f"for cryptocurrency markets (specifically Bitcoin):\n\n{value}"
)
# Run the server
if __name__ == "__main__":
mcp.run()