使用说明
mcp-x查询
A. 模型上下文协议(MCP) 服务器,让人工智能助手通过 格罗克API.
将此服务器连接到Claude Desktop(或任何兼容MCP的主机),并提出以下问题:
- “@sama本周发了什么推特?”
- “给我看看从这条推文开始的完整帖子。”
- “现在科技界的趋势是什么?”
- “查找有关最新GPT版本的推文。”
目录
特性
| 工具 | 说明 |
|---|---|
get_tweet |
通过ID或URL检索单个推文——Grok Vision自动分析的图像/视频 |
get_tweet_replies |
获取推文的回复,按参与度排序,日期范围可选 |
get_user_tweets |
用户最近的推文,可选择日期范围和媒体内容 |
get_user_profile |
完整资料:个人简介、关注者、固定推文等。 |
search_tweets |
使用推特运营商、日期范围和媒体丰富功能进行全文搜索 |
get_thread |
从任何推文重建的完整对话线程 |
get_trending |
当前热门话题,可选择按类别和国家过滤 |
analyze_sentiment |
推文语料库的情感分析(按查询或帐户,带语言过滤器) |
analyze_thread |
对一条线索的全面分析:情感、关键论点、总结 |
extract_links |
提取并汇总帐户共享的所有外部链接 |
get_user_mentions |
来自其他帐户的推文提及用户,日期范围可选 |
get_list_tweets |
按ID或URL从Twitter/X列表中发布推文,带有可选日期范围、分页光标和媒体丰富功能 |
先决条件
安装
git clone https://github.com/IvyNotFound/mcp-x-query.git
cd mcp-x-query
npm install
npm run build
配置
复制环境模板并添加您的API密钥:
cp .env.example .env
# Edit .env and set XAI_API_KEY=xai-...
服务器读取 XAI_API_KEY 启动时从环境中退出,如果丢失,则立即退出。
可用工具
get_tweet
检索一条包含完整元数据(媒体、引用推文、参与度指标)的推文。
当推文包含图像、视频或GIF时,每个媒体项目都会被自动分析 Grok Vision (grok-2-vision-1212)并丰富了a media_summary 描述视觉内容的字段。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
tweet_id_or_url |
string | 是 | 推特ID或完整的x.com/twitter.com URL |
get_tweet_replies
返回推特上参与度最高的回复,可选择按日期过滤。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
tweet_id_or_url |
string | 是 | 推特ID或URL |
max_results |
number | No | 1–100,默认值10 |
from_date |
string | 否 | YYYY-MM-DD |
to_date |
string | 否 | YYYY-MM-DD |
get_user_tweets
获取用户最近的推文和转发(最新优先)。通过 enrich_media: true 让Grok Vision分析每个媒体项目(增加延迟)。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
username |
string | 是 | 有或没有处理 @ |
max_results |
number | No | 1–100,默认值10 |
from_date |
string | 否 | YYYY-MM-DD |
to_date |
string | 否 | YYYY-MM-DD |
enrich_media |
boolean | 否 | true =添加 media_summary 通过Grok Vision(较慢) |
get_user_profile
返回完整的个人资料信息,包括个人简介、计数器和固定推文。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
username |
string | 是 | 有或没有处理 @ |
search_tweets
支持全文搜索 推特搜索运营商 (from:, to:, -is:retweet, lang:, #hashtag等等)。通过 enrich_media: true 用于Grok Vision对每个媒体项目的分析。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
query |
string | 是 | 搜索查询 |
max_results |
number | No | 1–100,默认值10 |
from_date |
string | 否 | YYYY-MM-DD |
to_date |
string | 否 | YYYY-MM-DD |
enrich_media |
boolean | 否 | true =添加 media_summary 通过Grok Vision(较慢) |
get_thread
从链中的任何推文(根、中间线程或叶子)重建完整的对话线程。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
tweet_id_or_url |
string | 是 | 线程中的任何推文 |
max_tweets |
number | No | 1–50,默认值为20 |
verbose |
boolean | 否 | true =完整字段(媒体、引用的推文);限制为10条推文以避免截断 |
get_trending
返回Twitter/X上的当前趋势主题。结果缓存5分钟,以避免重复的API调用。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
category |
string | 否 | 例如。 "technology", "sports", "politics" |
country |
string | 否 | 例如。 "France", "United States", "worldwide" |
analyze_sentiment
对通过搜索查询或从特定帐户检索到的推文语料库进行情绪分析。返回细分(正/负/中性百分比)、热门主题和值得注意的推文。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
query |
string | 是 | 搜索查询(支持Twitter运营商) |
username |
string | 否 | 限制对此帐户的推文进行分析(有或没有 @) |
max_tweets |
number | No | 1–100,默认值为30 |
from_date |
string | 否 | YYYY-MM-DD |
to_date |
string | 否 | YYYY-MM-DD |
language |
string | 否 | BCP-47语言代码过滤器(例如。 "fr", "en") |
analyze_thread
重建一个完整的线程,然后生成一个结构化的分析:总体情绪、每个参与者提出的关键论点、摘要和值得注意的引文。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
tweet_id_or_url |
string | 是 | 线程中的任何推文 |
max_tweets |
number | No | 1–50,默认值为20 |
extract_links
提取Twitter帐户共享的所有外部URL(或匹配搜索查询),并返回每个链接及其标题、域和共享内容的简要摘要。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
username |
string | 是 | 有或没有处理 @ |
max_tweets |
number | No | 1–100,默认值50 |
from_date |
string | 否 | YYYY-MM-DD |
to_date |
string | 否 | YYYY-MM-DD |
get_user_mentions
返回其他帐户中提到给定用户的推文。可用于监控品牌提及、社区回复或跟踪围绕特定句柄的对话。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
username |
string | Yes | 查找提及的句柄(有或没有) @) |
max_results |
number | No | 1–100,默认值10 |
from_date |
string | 否 | YYYY-MM-DD |
to_date |
string | 否 | YYYY-MM-DD |
get_list_tweets
从Twitter/X列表中获取最近的推文。接受数字列表ID或完整列表URL(https://x.com/i/lists/<ID>).支持通过光标分页: next_cursor 响应中的字段是页面上最旧推文的ID——将其作为 cursor 在下一次调用中获取旧推文。通过 enrich_media: true 让Grok Vision分析每个媒体项目(增加延迟)。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
list_id |
string | Yes | 数字列表ID(例如。 "1234567890")或完整URL(https://x.com/i/lists/1234567890) |
max_results |
number | No | 1–100,默认值10 |
from_date |
string | 否 | YYYY-MM-DD |
to_date |
string | 否 | YYYY-MM-DD |
cursor |
string | 否 | 分页光标: next_cursor 来自上一个响应的值 |
enrich_media |
boolean | 否 | true =添加 media_summary 通过Grok Vision(较慢) |
Claude桌面设置
将服务器添加到Claude Desktop配置文件中:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
窗户: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"mcp-x-query": {
"command": "node",
"args": ["/absolute/path/to/mcp-x-query/dist/index.js"],
"env": {
"XAI_API_KEY": "xai-your-api-key-here"
}
}
}
}
保存文件后重新启动Claude Desktop。
发展
# Watch mode — recompiles on every file save
npm run dev
# Single build
npm run build
# Interactive MCP inspector (useful for manual tool testing)
npm run inspector
TypeScript源代码位于 src/。编译后的输出将转到 dist/ (忽略了)。
项目结构
src/
├── index.ts # MCP server entry point — tool registration & startup (12 tools)
├── lib/
│ ├── grok-client.ts # Grok API wrapper (OpenAI SDK + x_search tool, maxRetries: 3)
│ ├── errors.ts # Typed error hierarchy: GrokError, GrokAuthError, GrokRateLimitError
│ ├── utils.ts # Input helpers: URL→ID extraction, @ stripping, escapeForPrompt
│ └── cache.ts # TtlCache<K,V>: in-memory TTL cache (used by get_trending, get_user_profile)
├── schemas/
│ ├── tweet.ts # TweetSchema, ThreadSchema, TweetArraySchema, MediaSchema
│ ├── user.ts # UserProfileSchema
│ ├── trending.ts # TrendingTopicsSchema
│ ├── sentiment.ts # SentimentAnalysisSchema, SentimentBreakdownSchema, NotableTweetSchema
│ ├── thread-analysis.ts# ThreadAnalysisSchema
│ └── link-extract.ts # LinkExtractSchema, ExtractedLinkSchema
└── tools/ # One file per MCP tool
├── get-tweet.ts
├── get-tweet-replies.ts
├── get-user-profile.ts
├── get-user-tweets.ts
├── get-thread.ts
├── get-trending.ts
├── search-tweets.ts
├── analyze-sentiment.ts
├── analyze-thread.ts
├── extract-links.ts
├── get-user-mentions.ts
└── get-list-tweets.ts
测试
# Unit tests only — no API key required, runs in < 5 s
npm test
# Unit tests with coverage report (thresholds: lines 60%, functions 60%, branches 50%)
npm run test:coverage
# Integration tests — makes real Grok API calls (requires XAI_API_KEY in .env.test)
cp .env.test.example .env.test
# Edit .env.test and set XAI_API_KEY=xai-..., then:
npm run test:integration
# All tests (unit + integration)
npm run test:all
测试类型:
| 文件 | 类型 | 测试 | 需要API密钥 |
|---|---|---|---|
src/tests/utils.test.ts |
单元 | 25 | 否 |
src/tests/cache.test.ts |
单元 | 7 | 否 |
src/tests/schemas.test.ts |
单元--MCP模式快照 | 12 | 否 |
src/tests/tools.test.ts |
单位(嘲笑Grok客户) | 89 | 否 |
src/tests/mcp.test.ts |
集成-实际Grok API调用 | 8 | 是 |
建筑
MCP Host (e.g. Claude Desktop)
│ stdio (JSON-RPC)
▼
src/index.ts ←── registers 12 tools, wraps errors via run()
│
▼
GrokClient.query() GrokClient.analyzeMedia()
(maxRetries: 3) (get_tweet only)
│ HTTPS │ HTTPS
▼ ▼
api.x.ai/v1 ── x_search ──▶ Twitter/X real-time data
api.x.ai/v1 ── chat/completions (grok-2-vision-1212) ──▶ media_summary
关键设计决策:
- 模式驱动的响应:每个工具都使用Zod模式来定义确切的JSON形状。
GrokClient将其转换为JSON模式($refStrategy: "none"避免$ref节点Grok拒绝)并通过以下方式验证解析后的响应schema.parse(). - 精简与冗长线程模式:线程默认为最小架构,以保持在令牌限制范围内。通过
verbose: true当你需要完整的元数据(最多10条推文)时。 - 输入标准化:
extractTweetId处理原始ID和完整URL。sanitizeUsername带状导线@。所有工具都接受用户友好的输入。 - 类型化错误层次结构:
src/lib/errors.ts定义GrokError,GrokAuthError(401),以及GrokRateLimitError(429).这run()助手会区分这些以获得更好的日志消息,并始终返回有效的MCP响应形状。 - 媒体丰富:
get_tweet通过执行第二个API调用GrokClient.analyzeMedia()取完之后。对于视频,使用缩略图帧;对于图像/GIF,直接URL。调用是即发即弃safe-记录故障并以静默方式跳过,因此总是返回tweet。 - 单次通话分析工具:
analyze_sentiment,analyze_thread,以及extract_links每个使用一个client.query()呼叫--x_search在同一推理步骤中进行提取和Grok分析。
安全
服务器内置了几种防御措施,以防止常见的攻击媒介:
| 测量 | 位置 | 它的作用 |
|---|---|---|
| API密钥验证 | src/index.ts |
拒绝不匹配的密钥 /^xai-[A-Za-z0-9]{40,}$/ 启动时 |
| 及时缓解注射 | src/lib/utils.ts — escapeForPrompt() |
替换 </> 随着 ‹/› 在将所有自由文本输入(查询、类别、语言)插入提示之前,都使用Unicode |
| 用户名净化 | src/lib/utils.ts — sanitizeUsername() |
条纹 @ 并且仅强制使用字母数字+下划线 |
| 推特ID验证 | src/lib/utils.ts — extractTweetId() |
如果提取的ID不是纯数字,则抛出(^\d+$) |
| 输入长度上限 | Zod模式 | query 字段的长度限制为500个字符 |
| 日期格式验证 | Zod模式 | 全部 from_date/to_date 字段需要 YYYY-MM-DD 通过正则表达式格式化 |
| API超时 | src/lib/grok-client.ts |
timeout: 30_000 所有API调用上的ms |
| 媒体域白名单 | src/lib/grok-client.ts |
analyzeMedia() 只接受来自一组固定的受信任域的URL(x.com, twimg.com等等) |
| TTL缓存 | src/lib/cache.ts |
缓存趋势主题(5分钟)和用户配置文件(10分钟),以减少API表面积 |
贡献
看 贡献.md.