@trendmoon/mcp-server
Version:
TrendMoon MCP Server - Library and Standalone Server for Cryptocurrency and Social Data
222 lines • 11.7 kB
JavaScript
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { TrendmoonApiClient, CategoryService, ChatService, CoinService, MessageService, SocialService, UserService, ChatActivityService } from "@trendmoon/api-client";
import { z } from "zod";
import { registerBinanceTools } from '../tools/BinanceTools.js';
import { registerCategoryTools } from '../tools/CategoryTools.js';
import { registerChatActivityTools } from '../tools/ChatActivityTools.js';
import { registerChatTools } from '../tools/ChatTools.js';
import { registerCoinTools } from '../tools/CoinTools.js';
import { registerMessageTools } from '../tools/MessageTools.js';
import { registerSocialTools } from '../tools/SocialTools.js';
import { registerUserTools } from '../tools/UserTools.js';
export class TrendmoonMcpServer {
mcpServer;
trendmoonApiClient;
services;
constructor(config = {}) {
this.mcpServer = new McpServer({
name: config.name || "trendmoon-mcp-tool-server",
version: config.version || "1.0.0",
});
this.trendmoonApiClient = new TrendmoonApiClient();
this.services = {
category: new CategoryService(this.trendmoonApiClient),
chat: new ChatService(this.trendmoonApiClient),
coin: new CoinService(this.trendmoonApiClient),
message: new MessageService(this.trendmoonApiClient),
social: new SocialService(this.trendmoonApiClient),
user: new UserService(this.trendmoonApiClient),
chatActivity: new ChatActivityService(this.trendmoonApiClient),
};
this.registerAllTools();
this.registerPrompts();
}
registerAllTools() {
registerCategoryTools(this.mcpServer, this.services.category);
registerChatTools(this.mcpServer, this.services.chat);
registerCoinTools(this.mcpServer, this.services.coin);
registerMessageTools(this.mcpServer, this.services.message);
registerSocialTools(this.mcpServer, this.services.social);
registerUserTools(this.mcpServer, this.services.user);
registerChatActivityTools(this.mcpServer, this.services.chatActivity);
registerBinanceTools(this.mcpServer);
}
registerPrompts() {
// this.mcpServer.prompt(
// "analyzeCoinPerformance",
// "Provides a performance analysis for a specific cryptocurrency over a given timeframe, focusing on details, social trends, and project summary.",
// {
// symbol: z.string().describe("Cryptocurrency symbol (e.g., BTC, ETH). This is required."),
// timeframe: z.enum(["1h", "24h", "7d", "30d"]).optional()
// .describe("The timeframe for the analysis (e.g., '24h', '7d'). Defaults to '24h' if not provided.")
// },
// (args) => {
// const { symbol, timeframe = "24h" } = args;
//
// let dateIntervalDays: number;
// let apiTimeInterval: string;
//
// switch (timeframe) {
// case "1h":
// dateIntervalDays = 1;
// apiTimeInterval = '1h';
// break;
// case "24h":
// dateIntervalDays = 1;
// apiTimeInterval = '1d';
// break;
// case "7d":
// dateIntervalDays = 7;
// apiTimeInterval = '7d';
// break;
// case "30d":
// dateIntervalDays = 30;
// apiTimeInterval = '30d';
// break;
// }
//
// const dateToISO = new Date().toISOString();
// const dateFromISO = new Date(Date.now() - dateIntervalDays * 24 * 60 * 60 * 1000).toISOString();
//
// const userInstructions = `
// I need an analysis of the cryptocurrency ${symbol} over the last ${timeframe}. Please perform the following steps using the available TrendMoon tools:
//
// 1. **Fetch Basic Coin Details:**
// * Call the "getCoinDetails" tool with the parameter:
// * symbol: "${symbol}"
// * This will provide its name, market cap rank, and other fundamental metadata.
//
// 2. **Fetch Social Trend Data:**
// * Call the "getSocialTrend" tool with the parameters:
// * coin_ids: "${symbol}"
// * start_date: "${dateFromISO}" (representing the start of the ${timeframe} period)
// * end_date: "${dateToISO}" (representing the current time)
// * interval: "${apiTimeInterval}" (appropriate interval for the timeframe)
// * This will provide social mentions, dominance, and price time series if included by the API.
//
// 3. **Fetch AI Project Summary:**
// * Call the "getProjectSummary" tool with the parameters:
// * symbol: "${symbol}"
// * daysAgo: ${dateIntervalDays} (number of days of social data to analyze for the summary)
// * This will provide recent community sentiment, developments, and upcoming catalysts based on AI analysis.
//
// 4. **Synthesize and Report:**
// * Combine the information gathered from "getCoinDetails", "getSocialTrend", and "getProjectSummary".
// * Provide a concise report that includes:
// * Key details about ${symbol} (name, rank).
// * Highlights from the social trend data (e.g., general trend of mentions or sentiment if apparent from raw data).
// * Key takeaways from the project summary (community sentiment, recent developments).
// * An overall assessment of ${symbol}'s activity and sentiment based on these factors for the ${timeframe}.
// `;
//
// return {
// description: `Plan a performance analysis for ${symbol} over ${timeframe} using coin details, social trends, and project summary.`,
// messages: [
// {
// role: "user" as const,
// content: {
// type: "text" as const,
// text: userInstructions
// }
// }
// ]
// };
// }
// );
this.mcpServer.prompt("analyzeCoinPerformance", "Provides a performance analysis for a specific cryptocurrency over a given timeframe, focusing on details, social trends, and project summary.", {
symbol: z.string().describe("Cryptocurrency symbol (e.g., BTC, ETH). This is required."),
timeframe: z.enum(["1h", "24h", "7d", "30d"]).optional()
.describe("The timeframe for the analysis (e.g., '24h', '7d'). Defaults to '24h' if not provided.")
}, async (args) => {
const { symbol, timeframe = "24h" } = args;
try {
let dateIntervalDays;
switch (timeframe) {
case "1h":
dateIntervalDays = 1;
break;
case "7d":
dateIntervalDays = 7;
break;
case "30d":
dateIntervalDays = 30;
break;
default:
dateIntervalDays = 1;
break;
}
console.log(`[Prompt] Fetching data for ${symbol}...`);
const [coinDetails, socialTrend, projectSummary] = await Promise.all([
this.services.coin.getCoinDetails({ symbol }),
this.services.social.getSocialTrend({ symbol }),
this.services.social.getProjectSummary({ symbol, days_ago: dateIntervalDays })
]);
console.log(`[Prompt] Data for ${symbol} fetched successfully.`);
// 3. Synthétiser le rapport
const reportParts = [];
reportParts.push(`📊 **Performance Analysis for ${symbol.toUpperCase()} (${timeframe})**\n`);
if (coinDetails) {
reportParts.push('**Coin Details:**');
let detailsText = `- Name: ${coinDetails.name || 'N/A'}\n`;
detailsText += `- Symbol: ${coinDetails.symbol || 'N/A'}\n`;
detailsText += `- Market Cap Rank: #${coinDetails.market_cap_rank || 'N/A'}`;
reportParts.push(detailsText);
}
else {
reportParts.push('**Coin Details:** Could not be fetched.');
}
if (socialTrend?.trend_market_data?.length > 0) {
const latestTrend = socialTrend.trend_market_data[socialTrend.trend_market_data.length - 1];
reportParts.push('\n**Social Snapshot:**');
let socialText = `- Social Mentions: ${latestTrend.social_mentions?.toLocaleString() || 'N/A'}\n`;
socialText += `- Social Dominance: ${latestTrend.social_dominance ? (latestTrend.social_dominance * 100).toFixed(2) + '%' : 'N/A'}`;
reportParts.push(socialText);
}
else {
reportParts.push('\n**Social Snapshot:** No recent social trend data available.');
}
if (projectSummary?.summary) {
reportParts.push('\n**AI Project Summary:**');
reportParts.push(projectSummary.summary);
}
else {
reportParts.push('\n**AI Project Summary:** No AI summary could be generated.');
}
const finalReport = reportParts.join('\n');
return {
messages: [
{
role: "assistant",
content: {
type: "text",
text: finalReport
}
}
]
};
}
catch (error) {
console.error(`[Prompt Error] Failed to analyze ${symbol}:`, error);
const errorMessage = `❌ An error occurred while analyzing ${symbol}. Please check the server logs for details.`;
return {
messages: [
{
role: "assistant",
content: {
type: "text",
text: errorMessage
}
}
]
};
}
});
}
getMcpServer() {
return this.mcpServer;
}
getServices() {
return this.services;
}
}
//# sourceMappingURL=TrendmoonMcpServer.js.map