Skip to main content
Glama
hn-mcp

hn-mcp

by tomwojcik

hn-mcp

PyPI Python 3.12+ codecov License: MIT

HN threads have 500+ comments nested 10 levels deep. Your AI agent needs to read them without blowing its context window.

hn-mcp is an MCP server that gives AI agents full access to Hacker News — complete comment trees, search, and user profiles — with depth control so they can explore progressively instead of fetching everything at once.

Features

  • Full comment trees — no depth limits, no truncation

  • Depth control — fetch just top-level comments or the entire tree

  • Smart pruning — reply_count at cut-off points so agents decide what to expand

  • Search — full-text search across stories and comments with filters

  • No API keys — uses the public Algolia HN API

  • 100% test coverage — tested with VCR cassettes, no network calls needed

Typical agent workflow

1. get_thread(42123456, depth=1)       → story + 85 top-level comments with reply_counts
2. Agent picks Comment A (47 replies)
3. get_comment_tree(comment_a_id)      → full 47-reply subtree
4. Agent summarizes branch, picks next

Or for smaller threads, just get_thread(id, depth=-1) to get the entire tree at once.

Getting started

Standard config works in most tools:

{
  "mcpServers": {
    "hn": {
      "command": "uvx",
      "args": ["hn-mcp"]
    }
  }
}
claude mcp add hn -- uvx hn-mcp

Add --scope user to make it available in all projects.

Follow the MCP install guide, use the standard config above.

Add to your Cursor MCP config (~/.cursor/mcp.json):

{
  "mcpServers": {
    "hn": {
      "command": "uvx",
      "args": ["hn-mcp"]
    }
  }
}

Follow the Windsurf MCP documentation, use the standard config above.

Add to your VS Code MCP config (.vscode/mcp.json):

{
  "mcpServers": {
    "hn": {
      "command": "uvx",
      "args": ["hn-mcp"]
    }
  }
}

If you want to run from a local clone instead:

claude mcp add hn -- uv run --directory /absolute/path/to/news-ycombinator-mcp hn-mcp

Prerequisites

  • Python 3.12+

  • uv (provides uvx)

Related MCP server: Hacker News MCP Server

Tools

Tool

Description

Key Inputs

Returns

get_thread

Fetch a story and its comment tree

story_id, depth (0=story only, 1=top-level, N=N levels, -1=full tree)

Story metadata + pruned comment tree

get_comment_tree

Dive into a specific comment's reply subtree

comment_id, depth (default: -1, full subtree)

Comment + nested replies

get_stories

Browse HN by category

category (top, new, ask_hn, show_hn), count

List of story summaries

search_stories

Full-text search for stories

query, sort_by (relevance/date), count, page

Paginated story results

search_comments

Full-text search for comments

query, sort_by, story_id, author, count, page

Paginated comment results

get_user

Fetch a user profile

username

Username, karma, about, created date

Depth parameter

The depth parameter on get_thread and get_comment_tree controls how much of the tree you get:

depth=0   (no comments — story metadata only)
depth=1   Comment A (reply_count=3)       ← just the comment + count
depth=2   Comment A                        ← comment + direct replies
            ├── Reply A1 (reply_count=2)
            ├── Reply A2 (reply_count=0)
            └── Reply A3 (reply_count=1)
depth=-1  Full tree, no pruning

Development

git clone https://github.com/tomwojcik/news-ycombinator-mcp
cd news-ycombinator-mcp
make venv
make install

Run tests

make test

Tests use vcrpy cassettes — no network calls needed. Coverage is reported automatically.

Re-record cassettes

If the Algolia API response format changes:

# In tests/conftest.py, temporarily change record_mode to "new_episodes"
uv run pytest
# Then change it back to "none"

Project structure

src/hn_mcp/
├── app.py               # FastMCP instance + tree pruning helpers
├── client.py            # HNClient — async Algolia API client
├── server.py            # Entrypoint
├── types.py             # TypedDict definitions for all responses
└── tools/
    ├── get_thread.py
    ├── get_comment_tree.py
    ├── get_stories.py
    ├── search_stories.py
    ├── search_comments.py
    └── get_user.py

License

MIT — see LICENSE.

Contributing

Contributions welcome. Please open an issue first to discuss what you'd like to change.

When submitting a PR:

  1. Add tests for new functionality

  2. Record VCR cassettes for any new API calls

  3. Ensure uv run pytest passes with 100% coverage

Available Tools

6 tools
get_comment_treeA

Fetch a specific comment and its reply subtree.

Use this to dive into a branch after scanning top-level comments
with get_thread(depth=1).

Args:
    comment_id: The HN comment ID.
    depth: How many levels of replies to include below this comment.
        0 = this comment only (with reply_count).
        N = N levels of replies.
        -1 = full subtree (default).

Inputs: comment_id (required), depth. Returns: result

get_storiesA

Browse HN stories by category. Returns metadata only (no comments).

Args:
    category: One of: top, new, ask_hn, show_hn.
    count: Number of stories to return (default 20, max 100).

Inputs: category (required), count. Returns: result

get_threadA

Fetch a story and its comment tree from Hacker News.

Args:
    story_id: The HN story ID.
    depth: How many levels of comment nesting to include.
        0 = story metadata only, no comments.
        1 = top-level comments only (each includes reply_count).
        2 = top-level + their direct replies.
        N = N levels deep.
        -1 = entire tree, no limits.

Inputs: story_id (required), depth. Returns: result

get_userB

Fetch a Hacker News user profile.

Args:
    username: The HN username.

Inputs: username (required). Returns: result

search_commentsA

Full-text search for HN comments.

Args:
    query: Search terms.
    sort_by: "relevance" or "date".
    story_id: Optional — only search comments on this story.
    author: Optional — only search comments by this author.
    count: Results per page (default 20, max 100).
    page: Page number, 0-indexed.

Inputs: query (required), page, count, author, +2 more. Returns: result

search_storiesA

Full-text search for HN stories.

Args:
    query: Search terms.
    sort_by: "relevance" or "date".
    count: Results per page (default 20, max 100).
    page: Page number, 0-indexed.

Inputs: query (required), page, count, sort_by. Returns: result

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.2/5.0

    Scored across 6 tools

    Disambiguation5/5

    Each tool addresses a distinct purpose: browsing story lists, fetching a story with comments, drilling into a comment subtree, retrieving user profiles, and searching stories/comments. No overlap in core functionality.

    Naming Consistency5/5

    All retrieval tools follow a consistent 'get_' prefix, while search tools use 'search_', making the naming pattern predictable and easy to navigate.

    Tool Count5/5

    Six tools cover the essential read-only operations for Hacker News without excessive granularity or unnecessary overlap, which is well-scoped for the domain.

    Completeness5/5

    The toolkit provides comprehensive coverage for browsing HN: story feeds, story/comment retrieval with configurable depth, user profiles, and full-text search for both stories and comments. No obvious gaps for a read-only client.

    Maintenance

    ActivitySlowing
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      D
      maintenance
      A Model Context Protocol server that enables AI tools like Claude and Cursor to fetch and interact with live Hacker News data (posts, comments, users) via standardized MCP endpoints.
      11
      227 npm
      35
      MIT
    • A
      license
      D
      quality
      D
      maintenance
      An MCP server that enables AI assistants to access real-time Hacker News data including top stories, story details, comments, and search functionality.
      1
      42 npm
      3
      MIT