Skip to main content
Glama
Xxx00xxX33

FinanceMCP

by Xxx00xxX33

hot_news_7x24

Access financial, political, tech, sports, entertainment, military, social, and international news from Tushare API with content deduplication for relevant updates.

Instructions

7x24热点:从Tushare新闻接口获取最新的财经、政治、科技、体育、娱乐、军事、社会、国际等新闻

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
limitNo返回条数,默认100,上限1500。接口按此数量向Tushare请求后再进行内容相似度去重

Implementation Reference

  • Core handler logic: validates limit, fetches raw news from Tushare API, deduplicates using 80% Jaccard similarity on title+summary bigrams, formats as markdown list with source/day stats, handles errors and empty results.
    async run(_args?: { limit?: number }) {
      try {
        const logs: string[] = [];
        const rawLimit = typeof _args?.limit === 'number' && isFinite(_args.limit) ? Math.floor(_args.limit) : 100;
        const limit = Math.min(1500, Math.max(1, rawLimit));
        logs.push(`[START] hot_news_7x24 获取最新批次(limit=${limit})`);
        const raw = await fetchTushareNewsBatch(limit, logs);
        const deduped = deduplicateByContent(raw, 0.8);
        logs.push(`[INFO] 去重后条数: ${deduped.length}`);
    
        if (deduped.length === 0) {
          const hint = '可能原因:1) 未配置 Tushare Token;2) 被频控限制;3) 网络/服务异常。';
          return { content: [
            { type: 'text', text: `# 7x24 热点\n\n暂无数据\n${hint}` },
            { type: 'text', text: `## 调用日志\n\n${logs.join('\n')}` }
          ] };
        }
    
        // 逐条仅展示摘要(如有标题可作为前缀),不展示来源/时间/分隔线
        const formattedList = deduped.map(n => {
          const title = n.title ? `${n.title}\n` : '';
          return `${title}${n.summary}`.trim();
        }).join('\n---\n\n');
    
        // 底部统计:来源统计 + 时间范围/日期
        const sourceCounts = new Map<string, number>();
        const daySet = new Set<string>();
        for (const n of deduped) {
          sourceCounts.set(n.source, (sourceCounts.get(n.source) || 0) + 1);
          const day = (n.publishTime || '').split(' ')[0] || '';
          if (day) daySet.add(day);
        }
        const sourceStats = Array.from(sourceCounts.entries())
          .sort((a,b) => b[1]-a[1])
          .map(([s, c]) => `${s}: ${c}`)
          .join(',');
        const uniqueDays = Array.from(daySet.values()).sort();
        const dayInfo = uniqueDays.length ? `日期:${uniqueDays.join('、')}` : `日期:未知`;
    
        const footer = `\n\n—\n统计:共 ${deduped.length} 条;来源分布:${sourceStats || '无'}\n${dayInfo}\n数据来源:Tushare 新闻快讯 (<https://tushare.pro/document/2?doc_id=143>)`;
    
        return {
          content: [
            { type: 'text', text: `# 7x24 热点(按80%相似度降重)\n\n${formattedList}${footer}` }
          ]
        };
      } catch (error) {
        return { content: [{ type: 'text', text: `# 7x24 热点 获取失败\n\n错误: ${error instanceof Error ? error.message : '未知错误'}` }] };
      }
    }
  • JSON Schema for tool input: optional 'limit' (number, 1-1500, default 100) controlling batch size before deduplication.
    parameters: {
      type: 'object',
      properties: {
        limit: {
          type: 'number',
          description: '返回条数,默认100,上限1500。接口按此数量向Tushare请求后再进行内容相似度去重',
          minimum: 1,
          maximum: 1500
        }
      }
    },
  • src/index.ts:401-403 (registration)
    Tool dispatch registration in stdio MCP server (index.ts): maps 'hot_news_7x24' calls to hotNews.run(), normalizes result.
    case "hot_news_7x24": {
      return normalizeResult(await hotNews.run({}));
    }
  • Tool dispatch registration in HTTP MCP server (httpServer.ts): maps 'hot_news_7x24' calls to hotNews.run().
    case 'hot_news_7x24':
      return await hotNews.run({});
  • Key helper: Fetches latest news batch from Tushare 'news' API endpoint using POST with token, timeout/abort, parses response, maps to NewsItem, logs progress/errors.
    async function fetchTushareNewsBatch(maxTotal: number, logs?: string[]): Promise<NewsItem[]> {
      if (!TUSHARE_CONFIG.API_TOKEN) {
        logs?.push('[WARN] 未配置 TUSHARE_TOKEN,无法从 Tushare 获取数据');
        return [];
      }
      const controller = new AbortController();
      const timeoutId = setTimeout(() => controller.abort(), TUSHARE_CONFIG.TIMEOUT);
      try {
        const body = {
          api_name: 'news',
          token: TUSHARE_CONFIG.API_TOKEN,
          // 不传任何筛选参数,直接获取默认的最新数据
          params: {},
          fields: 'datetime,content,title,channels'
        } as const;
        const resp = await fetch(TUSHARE_CONFIG.API_URL, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(body),
          signal: controller.signal
        });
        clearTimeout(timeoutId);
        if (!resp.ok) {
          const msg = `Tushare请求失败: HTTP ${resp.status}`;
          logs?.push(`[ERROR] ${msg}`);
          return [];
        }
        const data = await resp.json();
        if (data.code !== 0) {
          const msg = `Tushare返回错误: ${data.msg || data.message || '未知错误'}`;
          logs?.push(`[ERROR] ${msg}`);
          return [];
        }
        const fields: string[] = data.data?.fields ?? [];
        const items: any[][] = data.data?.items ?? [];
        const idxDatetime = fields.indexOf('datetime');
        const idxContent = fields.indexOf('content');
        const idxTitle = fields.indexOf('title');
        const results: NewsItem[] = [];
        for (const row of items) {
          if (results.length >= maxTotal) break;
          const title = String(row[idxTitle] ?? '').trim();
          const content = String(row[idxContent] ?? '').trim();
          const datetime = String(row[idxDatetime] ?? '').trim();
          results.push({
            title,
            summary: content,
            url: '',
            source: 'Tushare',
            publishTime: datetime,
            keywords: []
          });
        }
        logs?.push(`[INFO] 从 Tushare 获取原始条数: ${results.length}`);
        return results;
      } catch (err) {
        clearTimeout(timeoutId);
        const msg = `获取Tushare新闻失败: ${err instanceof Error ? err.message : String(err)}`;
        console.error(msg);
        logs?.push(`[ERROR] ${msg}`);
        return [];
      }
    }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Xxx00xxX33/FinanceMCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server