hn-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@hn-mcp show me the top 10 stories on Hacker News right now"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
hn-mcp
An MCP server for Hacker News. Built against the 2026-07-28 protocol revision and MCP Python SDK v2.
Five read-only tools:
Tool | Does |
| Browse a feed (top / new / best / ask / show / job) |
| One story, job or poll by id |
| A story plus its comment thread, flattened and capped |
| Full-text and date-filtered search over all HN history |
| A user profile |
Run it
uv sync
uv run mcp dev src/hn_mcp/server.py # Inspector, stdio
uv run mcp run src/hn_mcp/server.py --transport streamable-http # HTTP
uv run pytest # 45 tests, no networkRelated MCP server: HN-MCP
Architecture
server.py MCP layer tool schemas, annotations, response models
| no I/O, no parsing
v
hn_client.py service layer Firebase + Algolia, fan-out, BFS, caching
|
v
models.py data layer Story / Comment / User, normalization
cache.py TTL cacheDependencies point one way only. models.py does not know MCP exists, which
is why it can be tested without starting a server.
Design notes
Two upstreams, one vocabulary. Feeds, items and users come from HN's
Firebase API; search comes from HN's Algolia index, because Firebase has no
search endpoint at all. They name the same concepts differently (by vs
author, score vs points, descendants vs num_comments), so both
parse into the same models. The model never learns there were two APIs.
Server-side fan-out. Firebase returns id lists, so a 30-story feed is 31 requests. Doing that in the server costs one tool call; making the model walk the ids costs 31 round trips with raw JSON in context each time.
Comment trees are breadth-first. HN ranks kids by its own ordering, so
breadth-first spends the comment budget on the highest-ranked comments across
the whole thread instead of exhausting it inside one argument. Nesting is
carried by an integer depth rather than nested objects, so the list stays
valid wherever it is cut.
Truncation is reported, never silent. When caps bite, truncated is true
and truncation_hint names the argument to raise. Each comment carries
num_replies, so the model can tell "no replies" from "replies you were not
shown" — a distinction it cannot otherwise make.
Errors are prompts. A failure says what went wrong, which tool to use
instead, and hands back the id needed to recover. Asking get_story for a
comment id returns the parent story's id rather than a validation error.
Constraints live in types. Literal feeds become schema enums;
Field(ge=, le=) becomes minimum/maximum. The docstring explains what
options mean; the type system enforces which are legal.
Stateless. The 2026-07-28 revision removed sessions, so the same code serves stdio and Streamable HTTP with no session plumbing. Any request can land on any instance.
Verified against live HN
search_stories and get_discussion have been run against the real API.
Doing so found three bugs the fixtures could not:
Breadth-first traversal with only a total cap spent the entire comment budget on top-level comments and returned one reply out of forty. Real threads are far wider than they are deep. Fixed with
max_top_level.The truncation hint asserted a rule of thumb instead of measuring, and was wrong about which comments had hidden replies. It now counts them.
Per-comment truncation was computed and discarded, leaving a trailing ellipsis indistinguishable from the author's own. Now
text_truncated.
tests/fake_hn.py carries a wide thread modelled on the real one so the
first of those cannot regress.
Not done yet
list_stories,get_storyandget_userhave not been exercised against live HN, only against fixtures.Never loaded into a host, so tool selection is untested: whether a model picks
search_storiesoverlist_storiesunprompted is the real measure of the docstrings, and it has not been measured.No rate limiting. Fine for stdio, needed before a public HTTP deployment.
search_storiesonly searches stories, not comments (tagsis fixed).
Available Tools
5 toolsget_discussionARead-only
Read a Hacker News comment thread in one call.
Returns the story plus a flat list of comments ordered breadth-first:
all top-level replies, then all of their replies, and so on. HN ranks
kids by its own ordering, so breadth-first spends the comment budget
on the highest-ranked comments across the whole thread rather than
exhausting it inside one argument.
Nesting is carried by each comment's depth rather than by nested
objects, so the list can be cut at any point and stay valid.
Popular threads are wide - often over a hundred top-level comments - so max_top_level bounds how many of them are opened. That is what leaves budget for replies: without it the comment cap is spent entirely on opening statements and no reply is ever reached. Lower it to read an argument in depth, raise it to survey opinions broadly.
Big threads will not fit. When anything is omitted, truncated is true
and truncation_hint names which argument to raise and why.
comments_with_hidden_replies counts how many returned comments have
replies that were left out, and top_level_shown against
top_level_total shows how much of the first level you are seeing.
Deleted and dead comments are skipped entirely.
Inputs: story_id (required), max_depth, max_comments, comment_chars, +1 more. Returns: A story with a flattened, capped slice of its comment tree.
get_storyARead-only
Fetch one Hacker News story, job or poll by id.
Use this when an id is already known - from list_stories, from search_stories, or from a news.ycombinator.com/item?id=N URL. Returns the story only; call get_discussion to read its comments.
Inputs: story_id (required). Returns: A story, job or poll - the unit an agent reasons about. Deliberately omits HN's…
get_userARead-only
Look up a Hacker News user profile.
Returns karma, account age, bio and submission count. Usernames are case-sensitive, and only accounts with public activity are exposed by HN's API.
This returns the profile, not the user's posts. To find what someone submitted, use search_stories.
Inputs: username (required). Returns: A Hacker News account.
list_storiesARead-only
Browse Hacker News story feeds.
Returns each story's title, score, author, comment count and links - enough to answer "what's on HN right now" in a single call.
Feeds: top front page, ranked by HN's algorithm. Also contains job posts new most recently submitted, unranked best highest-scoring stories of the last few days ask Ask HN text and discussion posts show Show HN project launches job YC portfolio job postings
top and new hold up to 500 ids; ask, show and job hold up to 200, so a large limit on those feeds returns fewer stories than requested.
Every story carries an id. Pass it to get_discussion to read comments -
this tool returns no comment text.
Inputs: feed, limit, offset, min_score. Returns: A page of stories from a feed.
search_storiesARead-only
Full-text search across all of Hacker News history.
Use this for anything the feeds cannot answer: a topic, a company, a phrase, or anything older than the current front page. The feed tools only see what is on HN right now; this sees everything ever posted.
sort="relevance" is right for topic questions. sort="date" is right for "what is the latest on X", since the best match may be years old.
days_back filters by age, so days_back=30 with sort="date" answers "what has HN said about X recently".
Inputs: query (required), page, sort, limit, +1 more. Returns: Search hits from HN's Algolia index.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 5 tools
Each tool targets a distinct resource+action: search_stories is full-text history search, list_stories is live feeds, get_story is a single item by id, get_discussion is a comment thread, and get_user is a profile. The descriptions actively contrast the easily-confused pairs (search vs. feeds, story vs. discussion), so an agent can pick correctly without guessing.
All five tools follow the same verb_noun snake_case pattern (search_stories, list_stories, get_story, get_discussion, get_user). The verbs also map cleanly onto intent: list for collections, search for queries, get for single lookups.
Five tools is a tight, well-scoped surface for the Hacker News domain — search, browse, item, thread, user — with no filler or redundant variants. Each tool covers a workflow the others cannot answer.
Core lifecycle is covered: discovery via feeds/search, item retrieval, comment reading, and user lookup. The main gap is author-scoped browsing — get_user explicitly says to use search_stories for a user's submissions, but search_stories is documented only as text search, so per-user submission listing and single-comment/subthread fetch are workarounds rather than first-class operations.
Maintenance
Related MCP Connectors
Browse Hacker News feeds, threads, and user profiles with full-text search.
HN front-page, Algolia full-text search, and Show HN launch tracker.
Hacker News MCP — search and retrieve stories from Hacker News
Hacker News front page and search: stories, points, comments, and which stories link to your domain.
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables AI assistants to search, retrieve, and interact with HackerNews content including stories, comments, polls, and user information. Provides comprehensive access to all HackerNews API endpoints with 15 specialized tools for content discovery and analysis.1560 npm5MIT
- AlicenseAqualityDmaintenanceEnables browsing Hacker News, searching discussions, analyzing users, and tracking tech trends with zero setup required—no API keys or authentication needed.527 npm6MIT
- AlicenseAqualityDmaintenanceProvides programmatic access to Hacker News content via the HN Algolia API. It enables AI assistants to search stories, retrieve comments, access user profiles, and explore the front page in real-time.960 npmMIT
- FlicenseAqualityDmaintenanceEnables AI assistants to read and search Hacker News for top stories, comments, user profiles, and job listings using the Firebase and Algolia APIs. It facilitates natural language research into community discussions and technological trends across the HN platform.8-