mcpField
H
hn-mcp-server

hn-mcp-server

远程服务
github.com/cyanheads社交媒体5今天更新
代码仓库

关于 hn-mcp-server

用于浏览 Hacker News 信息流、讨论、用户资料和可搜索帖子的 MCP 服务,适合读者与研究人员。它提供分层评论、用户查询及由 Algolia 支持的内容搜索。

主要功能

  1. 01浏览六类 Hacker News 信息流
  2. 02分页读取评论串
  3. 03获取用户资料和投稿
  4. 04搜索故事、评论、投票和职位
  5. 05按作者、日期或分数筛选

适用场景

  1. 01跟踪最新或热门 Hacker News 帖子
  2. 02分段阅读较长讨论并继续翻页
  3. 03按关键词、作者或日期查找帖子

MCP 相关

提供四个工具,用于访问 Hacker News 信息流、讨论串、用户资料和内容搜索。MCP 客户端可通过 STDIO 或 Streamable HTTP 连接,也可使用托管端点。

配置

远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。

服务地址https://hn.caseyjhand.com/mcp
一键复制安装命令
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。

安装包
npm@cyanheads/hn-mcp-server0.6.0

工具

4
参数类型必填说明
feedenum是要获取的 HN 信息流。“top”包含 jobs。“ask”和“show”分别是 Ask HN / Show HN 帖子。top | new | best | ask | show | jobs
countinteger否要返回的帖子数量。数量越多,耗时越长。
offsetinteger否从信息流开头开始跳过的帖子数量。与 count 一起用于分页。

详细介绍

@cyanheads/hn-mcp-server

通过 MCP 浏览 Hacker News 信息流、讨论串和用户资料,并进行全文搜索。支持 STDIO 或 Streamable HTTP。

4 个工具

版本 许可证 Docker MCP SDK npm TypeScript Bun

在 Claude Desktop 中安装 在 Cursor 中安装 在 VS Code 中安装

框架

公共托管服务: https://hn.caseyjhand.com/mcp


概述

Hacker News 信息流、讨论串和用户资料。浏览排名信息流、阅读完整评论串、查询用户,并按关键词、作者、日期或分数搜索故事、评论、投票和招聘信息。

工具
工具描述
hn_get_stories从 HN 信息流(top、new、best、ask、show、jobs)获取故事,并返回标题、URL、分数、作者和评论数
hn_get_thread获取条目及其评论树,以讨论串形式呈现;支持控制深度和评论数,并提供游标以翻阅较长的讨论串
hn_get_user获取用户资料,包括 karma、about,以及可选的一页已解析投稿
hn_search_content通过 Algolia 搜索故事、评论、投票和招聘信息;可按关键词搜索、仅使用筛选条件搜索,或同时使用两者——筛选条件包括类型、作者、父故事、日期范围和最低分数

功能参考

hn_get_stories 工具
  • 六种动态类型:top、new、best、ask、show、jobs;count(默认值为 30)和 offset 用于分页。单次调用最多返回 100 条动态;count 最大可设为 1,000,但实际每次最多返回 100 条,并通过 notice 指明下一个 offset
  • 返回 id、类型、标题、url、域名、分数、作者、时间戳、评论数和正文文本;HN 未提供的字段会省略(而非设为 null)
  • 丰富结果会报告 total、offset 和 hasMore;还有动态时会设置 truncated,并通过 notice 指明下一个 offset;若页面为空(动态流为空、offset 超出范围,或页面中的所有条目都已删除或标记),则会通过 notice 说明。最后一页不会标记为截断
  • 多次重试后仍获取失败的条目会列在 failedIds 中,notice 会指出重试情况;若页面中的所有条目都获取失败,则会返回分类后的上游错误,而非空列表

hn_get_thread 工具
  • itemId 加上 depth(默认值为 3;设为 0 时只返回条目,不含评论)和 maxComments(默认值为 50),用于限制单次响应中所有层级的评论总数;此外还有固定的 64,000 字节文本预算,截断时只会在评论之间进行。单次调用最多解析 10 层和 200 条评论;depth 最大可设为 100,但实际最多解析 10 层;maxComments 最大可设为 1,000,但实际最多解析 200 条,并通过 notice 指明应作为 itemId 传入的评论,或可用于获取剩余内容的 nextCursor
  • 按 HN 的排名进行广度优先遍历:先解析排名最高的顶层评论,只有在上一层全部解析完后才填充回复
  • 可续传:响应因 maxComments、字节预算或上游速率限制而停止时,会返回 nextCursor;将其与相同的 itemId 一起作为 cursor 传入,即可从下一条尚未见过的评论继续。游标包含未访问的评论本身,因此重新排名的回复不会使游标偏移,且服务端不保存会话状态。工具未签发的游标、被修改的游标,或与不同 itemId 一起传入的游标,都会导致 invalid_cursor
  • 根条目包含其关系和状态:对于评论,包含 parent 和 storyId(讨论所属的故事或投票);对于投票选项,包含 poll;对于投票,包含 parts 和已解析的 options(所有深度下的文本和票数);以及 deleted/dead 标记。content[] 标题会注明类型——标题、Comment by <author>、Poll option by <author> on poll <id>——并标记已删除或已失效的根条目
  • 扁平评论列表包含用于重建树结构的 depth/parentId,以及 childCount;如果评论作者发布了该讨论所属的故事,还会包含 isOp 标记。对于评论根条目,故事作者通过 storyId 指定,绝不会使用评论本身的作者。失效和已删除的评论会被省略,但其有效回复仍会按真实的 depth 返回,parentId 指向被省略的评论
  • 仅当仍有未读取的评论时才会设置 truncated 和 truncationReason(count、size、rate_limited;若回复位于深度限制以下,则为 depth);终止页不会设置这些字段,包括恰好达到上限且完整加载的讨论串。notice 会报告遍历期间省略的已删除或失效评论,以及下一步操作:使用游标、增大 depth,或将评论 id 作为 itemId;对于因深度限制而被截断回复的已省略评论,会在 notice 中指出其 id
  • 多次重试后仍获取失败的评论和投票选项会列在 failedIds 中,notice 会指出这些条目及重试情况;获取失败的评论会保留在 nextCursor 中,因此翻页重试时会重新获取,而不会跳过。仍会返回根条目,且绝不会将获取失败伪装成 maxComments/depth 限制
hn_get_user 工具
  • username 区分大小写,且会去除首尾空格;includeSubmissions(默认值为 false)会解析近期提交内容,并通过 submissionCount(默认值为 10)和 submissionOffset 分页浏览较长的历史记录。每次调用最多解析 50 条提交内容;如果 submissionCount 不超过 1,000,则会以每批 50 条的方式提供,并通过 notice 指明下一个 submissionOffset
  • 个人资料包含 karma、创建日期和关于文本(会去除 HTML);提交内容会过滤掉已删除或已标记为无效的条目
  • 评论提交内容包含其 parent,投票选项提交内容包含其 poll,因此两者都能链接回所回复的内容
  • 丰富结果会回显 submissionOffset 和下一个要发送的偏移量;如果请求的偏移量超出历史记录范围,则会返回一条提示
  • 重试后仍获取失败的提交内容会列在 failedIds 中,并通过 notice 指明重试情况;如果某个批次中的所有提交内容都获取失败,则返回已分类的上游错误

hn_search_content 工具
  • 支持全文 query,以及 tags(story/comment/poll/job/ask_hn/show_hn/front_page)、author(区分大小写的精确用户名)、storyId、dateRange 和 minPoints 筛选条件;可按相关性或日期排序;count(默认值为 30)和 page 用于分页。每次调用最多返回 50 条结果;count 不超过 1,000 时,将从请求页面的首条结果开始,以 50 条为一页返回,并通过 notice 指明接下来应传入哪个 count: 50 页面;如果非零 page 的首条结果不在任何一页 50 条结果的开头,则会失败并返回 count_page_unaligned,同时指出能从该位置开始的 count 和 page,且当该 count 小于 25 时,还会指出包含该结果的 50 条结果页面
  • tags: "front_page" 表示当前首页(约 30 篇故事),不包括以往的首页;要查询更早的时间段,请使用 tags: "story"、dateRange 和 minPoints
  • 设置筛选条件时,query 为可选项——可单独列出 Ask HN、Show HN、投票或招聘信息,或者传入某篇故事的 storyId 并设置 tags: "comment",以搜索单个讨论串。没有 query 也没有筛选条件时,会失败并返回 missing_query_or_filter
  • 要检查某个网页是否被讨论过,请将其 URL 单独作为 query 传入:搜索前会去掉开头的 http://、https:// 或 www.,因此带或不带 www.、使用任一协议的提交都能匹配。输出中的 query 和 notice 会显示实际搜索的内容
  • dateRange 边界接受 ISO 8601 格式(YYYY、YYYY-MM、YYYY-MM-DD,或带可选偏移量的日期时间),按 UTC 解读,且两端均为开区间;范围为空或顺序错误时,会失败并返回 invalid_date_range
  • minPoints 适用于故事和投票——评论和招聘信息没有积分,因此与 tags: "comment" 或 "job" 同时使用时会失败并返回 min_points_unscored_type
  • view: "compact" 会省略两个正文文本字段(text、highlights.text);否则每条结果中的长评论会重复出现两次——传入结果 ID 到 hn_get_thread 即可读取正文
  • 当 Algolia 有记录时,每条结果都带有 type(story、comment、poll、pollopt、job)。未指定标签的搜索也会返回投票选项,这类结果仅包含 ID、作者、投票数和日期——使用 hn_get_thread 可读取投票选项的文本和所属投票。投票结果没有 storyId;其自身的 id 就是讨论根节点
  • 招聘信息描述会作为 text 返回,但关键词不会搜索这些描述
  • 高亮元数据(highlights.title、highlights.text、matchedWords)会显示匹配的词语及其位置
  • 丰富结果会回显已应用的 criteria——每个已设置的筛选条件(author 会去除首尾空格,dateRange 为实际应用的 UTC 开区间边界,精确到秒),以及填入默认值后的 sort、count 和 view——因此,保存的结果能说明其回答的内容
  • 丰富结果会报告 totalHits、page 和实际可访问的 totalPages——这些页数并非根据 totalHits 推算,因为宽泛查询的命中数远超 Algolia 可提供的范围。totalHitsExact: false 表示 totalHits 是估算值;reachableHits: 1000 表示匹配结果超过 Algolia 的 1,000 条上限;这类搜索的最后一页会通过 notice 指出该上限,并建议使用更窄的 dateRange 时间范围来获取其余结果。仍有更多页面时,会设置 truncated 并通过 notice 指出下一页的 page;请求超出末尾的页面时,会通过 notice 指出最后一个有效页面(超出上限时为 page: 0)

功能

基于 @cyanheads/mcp-ts-core 构建:支持 stdio 和 Streamable HTTP 传输、可插拔身份验证(none / jwt / oauth)、可切换存储(in-memory、filesystem、Supabase、Cloudflare KV/R2/D1),并提供结构化日志记录和可选的 OpenTelemetry 跟踪。

HN 专属功能:

  • 支持两个上游 API:用于获取信息流、条目和用户的 HN Firebase API;用于全文搜索的 Algolia HN Search API
  • 并发批量获取,在解析条目时可配置并行度(HN_CONCURRENCY_LIMIT)
  • 将 HTML 正文剥离为纯文本——实体只解码一次、代码块保持原样、每个链接只以其完整 URL 呈现一次;标题虽然不是 HTML,但有些包含实体,因此会进行实体解码,且绝不剥离标签
  • 在 initialize 时,将服务级别的 instructions 转发给大模型客户端——包括条目类型、跨工具复用 ID、区分大小写的用户名以及字段稀疏性
  • 无需 API 密钥——两个上游 API 均为公开 API

适合 Agent 使用的输出:

  • 优雅处理部分失败——条目重试后仍获取失败时,会按 ID 报告在 failedIds 中,而不是像已删除、已移除或不存在的条目那样被静默地从结果中剔除;hn_get_thread 还会统计被剔除的已删除和已移除评论;遇到受速率限制的条目时会停止整个批次,而不是让其余每个条目都单独经历重试流程
  • 区分式输出契约——提供带类型的错误原因(item_not_found、upstream_rate_limited、upstream_html 等)及每种原因对应的恢复文本(速率限制时会将上游的 Retry-After 作为 retryAfter 传递);每条评论都包含 depth/parentId 属性对,调用方无需猜测嵌套关系即可重建树结构
  • 分页来源信息——每个分页列表都会回显所用的偏移量(offset、submissionOffset、page)以及 notice 中的精确下一个偏移量;hn_search_content 还会回显搜索所用的 criteria;hn_get_thread 则会返回自包含的 nextCursor,让 Agent 无需重新计算状态即可继续处理
  • 响应整形——剥离 HTML、规范化 URL 和提取域名,以去除上游标记噪声;hn_search_content 的 view: "compact" 会省略两个正文文本字段,否则它们会与命中项的完整文本重复
  • 对上游文本进行围栏处理——在 content[] 中,正文的每一行都使用块引用格式,标题仅在可能破坏外围 Markdown 的位置进行转义,因此评论不会被误认为是服务器撰写的行

开始使用

公共托管实例

可通过 https://hn.caseyjhand.com/mcp 使用公共实例——无需安装。通过 Streamable HTTP 将任意 MCP 客户端指向该实例:

{
  "mcpServers": {
    "hn-mcp-server": {
      "type": "streamable-http",
      "url": "https://hn.caseyjhand.com/mcp"
    }
  }
}
自托管 / 本地运行

将以下内容添加到 MCP 客户端配置文件中:

{
  "mcpServers": {
    "hn-mcp-server": {
      "type": "stdio",
      "command": "bunx",
      "args": ["@cyanheads/hn-mcp-server@latest"],
      "env": {
        "MCP_TRANSPORT_TYPE": "stdio",
        "MCP_LOG_LEVEL": "info"
      }
    }
  }
}

或使用 npx(无需安装 Bun):

{
  "mcpServers": {
    "hn-mcp-server": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@cyanheads/hn-mcp-server"],
      "env": {
        "MCP_TRANSPORT_TYPE": "stdio",
        "MCP_LOG_LEVEL": "info"
      }
    }
  }
}

或使用 Docker:

{
  "mcpServers": {
    "hn-mcp-server": {
      "type": "stdio",
      "command": "docker",
      "args": [
        "run", "-i", "--rm",
        "-e", "MCP_TRANSPORT_TYPE=stdio",
        "ghcr.io/cyanheads/hn-mcp-server:latest"
      ]
    }
  }
}
前置条件
  • Bun v1.4.0 或更高版本(或 Node.js >= 24)
安装
git clone https://github.com/cyanheads/hn-mcp-server.git
cd hn-mcp-server
bun install

配置

所有配置均通过环境变量设置。无需 API 密钥——HN API 是公开的。

变量描述默认值
HN_CONCURRENCY_LIMIT批量获取条目时的最大并发 HTTP 请求数(整数,1–50)。10
MCP_TRANSPORT_TYPE传输方式:stdio 或 http。stdio
MCP_HTTP_PORTHTTP 服务端口。3010
MCP_HTTP_HOSTHTTP 服务主机。127.0.0.1
MCP_SESSION_MODEHTTP 会话处理方式:stateful、stateless 或 auto(解析为 stateful)。服务在源代码中声明为 stateless,发布的 Docker 镜像和 .env.example 也将其设为该值;仍可通过有意义的环境变量值进行覆盖。stateless
MCP_LOG_LEVEL日志级别:debug、info、notice、warning、error。info
LOGS_DIR日志文件目录(仅限 Node.js)。<project-root>/logs

完整的可选覆盖项列表请参见 .env.example。

运行服务

本地开发
  • 开发模式(自动重新加载):

    MCP_TRANSPORT_TYPE=stdio bun --watch src/index.ts   # stdio
    MCP_TRANSPORT_TYPE=http bun --watch src/index.ts    # HTTP
    
  • 构建并运行:

    bun run rebuild
    bun run start:stdio   # or start:http
    
  • 运行检查和测试:

    bun run devcheck   # Lint, format, typecheck, security
    bun run test       # Vitest test suite
    
Docker
docker build -t hn-mcp-server .
docker run --rm -p 3010:3010 hn-mcp-server

Dockerfile 默认使用 HTTP 传输、无状态会话模式,并将日志写入 /var/log/hn-mcp-server。默认会安装 OpenTelemetry 对等依赖项——构建时使用 --build-arg OTEL_ENABLED=false 可省略这些依赖项。

项目结构

目录用途
src/index.tscreateApp() 入口点——注册工具并初始化 HN 服务。
src/config/使用 Zod 解析和验证特定于服务的环境变量。
src/mcp-server/tools/definitions/工具定义(*.tool.ts)。
src/services/hn/HN Firebase + Algolia API 客户端和领域类型。
tests/与 src/ 结构对应的单元测试和集成测试。

开发指南

开发指南和架构规则请参阅 CLAUDE.md。简要来说:

  • 处理程序抛出异常,框架负责捕获——工具逻辑中不要使用 try/catch
  • 使用 ctx.log 记录请求范围内的日志
  • 所有工具均为只读——无需身份验证权限范围
  • 封装外部 API 调用:验证原始数据 → 规范化为领域类型 → 返回输出架构;绝不伪造缺失字段

贡献

欢迎提交问题。提交前请运行检查:

bun run devcheck
bun run test

许可证

Apache-2.0——详情请参阅 LICENSE。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。