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 [];
      }
    }
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It mentions the source ('Tushare新闻接口') and implies real-time/latest news ('最新的'), but lacks critical details: it doesn't specify authentication needs, rate limits, error handling, or what '7x24' operationally means. The schema description mentions content deduplication, but this isn't highlighted in the main description. For a news-fetching tool with zero annotation coverage, this is insufficient.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence that front-loads the core purpose. It wastes no words but could be slightly more structured (e.g., separating source from categories). However, it appropriately conveys the essential information without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the lack of annotations and output schema, the description is incomplete. It doesn't explain what the tool returns (e.g., news format, fields, timestamps) or behavioral aspects like pagination, rate limits, or error conditions. For a news-fetching tool that likely returns structured data, this leaves significant gaps for an AI agent to understand how to interpret results.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description adds no parameter information beyond what the schema provides. The input schema has 100% description coverage for the single parameter 'limit', detailing its purpose, default, range, and deduplication behavior. With high schema coverage and only one parameter, the baseline score of 3 is appropriate - the description doesn't compensate but doesn't need to given the schema's completeness.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: '从Tushare新闻接口获取最新的财经、政治、科技、体育、娱乐、军事、社会、国际等新闻' (fetch latest news from Tushare news API across multiple categories). It specifies the verb ('获取' - fetch), resource ('新闻' - news), and source ('Tushare新闻接口'). However, it doesn't explicitly differentiate from sibling tools like 'finance_news' - both appear to fetch news, though 'hot_news_7x24' emphasizes 'latest' and '7x24' (24/7) while 'finance_news' might be finance-specific.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. It doesn't mention sibling tools like 'finance_news' or explain scenarios where this tool is preferred (e.g., for broader news categories vs. finance-only). There's also no information about prerequisites, timing considerations, or when not to use it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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