Skip to main content
Glama

Hn Get Thread

hn_get_thread
Read-only

Get an item and its comment tree as a threaded discussion, with child comments resolved recursively. Use depth 0 for an item-only lookup. A long thread comes back in pages: pass the returned nextCursor as cursor to continue.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
depthNoHow many levels of replies to resolve. 0 = just the item, no comments. 1 = direct replies only. Replies below this depth are never fetched — to read them, raise depth or call again with a specific comment's itemId to drill into its subtree. Ignored when cursor is set: the depth the cursor was issued with applies.
cursorNonextCursor from a previous call, passed with the same itemId, to continue the traversal at the next unseen comment without repeating or skipping any. Omit to start from the top.
itemIdYesID of the story, comment, job, poll, or poll option to fetch the thread for.
maxCommentsNoMaximum comments in one response, across all depth levels. Highest-ranked top-level comments resolve first; replies fill in only after the level above is exhausted. A response also stops at a fixed 64,000-byte text budget. When either limit stops the traversal, nextCursor continues it.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
capNoThe maxComments cap that was applied.
itemNoThe root item: a story, comment, job, poll, or poll option.
errorNoPresent when the call failed. Absent on success.
shownNoNumber of comments returned.
noticeNoTraversal context: counts of deleted/dead comments dropped, the IDs that failed to load and how to retry them, then what stopped the traversal and how to continue — nextCursor for a count, size, or rate-limit stop, or a larger depth or a comment id as itemId for a depth cut. Absent when nothing was dropped, failed, or left unread.
commentsNoFlat comment list ordered breadth-first by rank: highest-ranked top-level comments first, then their replies. Use depth/parentId to reconstruct nesting. With cursor, the page continues the same order.
failedIdsNoComment and poll-option IDs whose fetch failed after retries, so neither they nor their replies are in this response. They are not deleted or missing and may load on a later call. Failed comments ride in nextCursor and are retried when you continue; without one, call again, or pass an ID as itemId to fetch that comment and its replies. Absent when everything the traversal reached loaded.
truncatedNoTrue when comments remain unread: reachable through nextCursor (truncationReason count, size, or rate_limited), or below the depth limit (depth). Absent on a terminal page — including a thread that loads in full at exactly maxComments.
nextCursorNoPass as cursor, with the same itemId, to continue from the next unseen comment. Present when truncationReason is count, size, or rate_limited; absent on the last page.
totalLoadedNoNumber of comments in this response (this page, when paging with cursor).
totalAvailableNoHN's total comment count for the root (descendants), which also counts dead and deleted comments. Absent for comment and job roots.
truncationReasonNoWhy the traversal stopped short: count = maxComments (or the 1,000-item ceiling per call) was reached; size = the 64,000-byte response budget was reached; rate_limited = the HN API throttled the fetches; depth = replies lie below the depth limit, which nextCursor does not reach — raise depth or pass a comment id as itemId. When a cursor reason and a depth cut both apply, the cursor reason is reported.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed22 schema fields changed
    • addedInput schema / properties / cursor
      Added value: +{
      +  "description": "nextCursor from a previous call, passed with the same itemId, to continue the traversal at the next unseen comment without repeating or skipping any. Omit to start from the top.",
      +  "type": "string"
      +}
    • changedInput schema / properties / depth / description
      Previous value: -"How many levels of replies to resolve. 0 = just the item, no comments. 1 = direct replies only. Popular stories often have more top-level comments than maxComments — to see nesting, raise maxComments together with depth, or call again with a specific comment's itemId to drill into a subtree."New value: +"How many levels of replies to resolve. 0 = just the item, no comments. 1 = direct replies only. Replies below this depth are never fetched — to read them, raise depth or call again with a specific comment's itemId to drill into its subtree. Ignored when cursor is set: the depth the cursor was issued with applies."
    • changedInput schema / properties / itemId / description
      Previous value: -"ID of the story, comment, or poll to fetch the thread for."New value: +"ID of the story, comment, job, poll, or poll option to fetch the thread for."
    • changedInput schema / properties / maxComments / description
      Previous value: -"Maximum total comments to include across all depth levels. Highest-ranked top-level comments resolve first; replies fill in only after the level above is exhausted."New value: +"Maximum comments in one response, across all depth levels. Highest-ranked top-level comments resolve first; replies fill in only after the level above is exhausted. A response also stops at a fixed 64,000-byte text budget. When either limit stops the traversal, nextCursor continues it."
    • changedOutput schema / properties / comments / description
      Previous value: -"Flat comment list ordered breadth-first by rank: highest-ranked top-level comments first, then their replies. Use depth/parentId to reconstruct nesting."New value: +"Flat comment list ordered breadth-first by rank: highest-ranked top-level comments first, then their replies. Use depth/parentId to reconstruct nesting. With cursor, the page continues the same order."
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `item_not_found`: HN reports no item exists for the given itemId. `upstream_rejected`: The HN API answered with a 4xx status other than 429 — it rejected the request as built. `upstream_rate_limited`: The HN API answered with HTTP 429. `upstream_unavailable`: The HN API answered with a 5xx status. `upstream_html`: The HN API served an HTML error page with a 200 status, which it does under rate limiting or maintenance. `upstream_malformed`: The HN API answered with a 200 status and a body that is not JSON. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `item_not_found`: HN reports no item exists for the given itemId. `invalid_cursor`: The cursor was issued for a different itemId than the one passed with it. `upstream_rejected`: The HN API answered with a 4xx status other than 429 — it rejected the request as built. `upstream_rate_limited`: The HN API answered with HTTP 429. `upstream_unavailable`: The HN API answered with a 5xx status. `upstream_html`: The HN API served an HTML error page with a 200 status, which it does under rate limiting or maintenance. `upstream_malformed`: The HN API answered with a 200 status and a body that is not JSON. Other values are possible when a failure originates below the handler."
    • changedOutput schema / properties / error / properties / data / properties / reason / examples
      Previous value: -[
      -  "item_not_found",
      -  "upstream_rejected",
      -  "upstream_rate_limited",
      -  "upstream_unavailable",
      -  "upstream_html",
      -  "upstream_malformed"
      -]New value: +[
      +  "item_not_found",
      +  "invalid_cursor",
      +  "upstream_rejected",
      +  "upstream_rate_limited",
      +  "upstream_unavailable",
      +  "upstream_html",
      +  "upstream_malformed"
      +]
    • addedOutput schema / properties / failedIds
      Added value: +{
      +  "description": "Comment and poll-option IDs whose fetch failed after retries, so neither they nor their replies are in this response. They are not deleted or missing and may load on a later call. Failed comments ride in nextCursor and are retried when you continue; without one, call again, or pass an ID as itemId to fetch that comment and its replies. Absent when everything the traversal reached loaded.",
      +  "items": {
      +    "type": "number"
      +  },
      +  "type": "array"
      +}
    • changedOutput schema / properties / item / description
      Previous value: -"The root item (story, comment, or poll)."New value: +"The root item: a story, comment, job, poll, or poll option."
    • addedOutput schema / properties / item / properties / dead
      Added value: +{
      +  "const": true,
      +  "description": "Present and `true` when the root is dead (flagged or killed); its replies are still walked. Omitted otherwise.",
      +  "type": "boolean"
      +}
    • addedOutput schema / properties / item / properties / deleted
      Added value: +{
      +  "const": true,
      +  "description": "Present and `true` when HN reports the root deleted; its author and text are gone, but its replies are still walked. Omitted otherwise.",
      +  "type": "boolean"
      +}
    • addedOutput schema / properties / item / properties / options
      Added value: +{
      +  "description": "For a poll root, its options with text and votes in parts order, resolved at every depth including 0. Deleted and dead options are kept and marked; an option whose fetch failed is listed in failedIds instead. Options do not count toward maxComments or totalLoaded.",
      +  "items": {
      +    "additionalProperties": false,
      +    "description": "One poll option.",
      +    "properties": {
      +      "dead": {
      +        "const": true,
      +        "description": "Present and `true` when the option is dead (flagged or killed). Omitted otherwise.",
      +        "type": "boolean"
      +      },
      +      "deleted": {
      +        "const": true,
      +        "description": "Present and `true` when the option was deleted. Omitted otherwise.",
      +        "type": "boolean"
      +      },
      +      "id": {
      +        "description": "Poll option ID.",
      +        "type": "number"
      +      },
      +      "score": {
      +        "description": "Votes for this option.",
      +        "type": "number"
      +      },
      +      "text": {
      +        "description": "Option text (HTML stripped). Absent once deleted.",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "id"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / item / properties / parent
      Added value: +{
      +  "description": "For a comment root, the ID of the story or comment it replies to — pass it as itemId for the context above.",
      +  "type": "number"
      +}
    • addedOutput schema / properties / item / properties / parts
      Added value: +{
      +  "description": "For a poll root, its option IDs in HN order.",
      +  "items": {
      +    "type": "number"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / item / properties / poll
      Added value: +{
      +  "description": "For a poll-option root, the ID of its poll.",
      +  "type": "number"
      +}
    • changedOutput schema / properties / item / properties / title / description
      Previous value: -"Story/job title."New value: +"Story/job/poll title."
    • addedOutput schema / properties / nextCursor
      Added value: +{
      +  "description": "Pass as cursor, with the same itemId, to continue from the next unseen comment. Present when truncationReason is count, size, or rate_limited; absent on the last page.",
      +  "type": "string"
      +}
    • changedOutput schema / properties / notice / description
      Previous value: -"Truncation context: counts of deleted/dead comments dropped during traversal, then either how to get past the maxComments cap when it stopped the traversal, or a raise-maxComments-or-depth hint when totalLoaded < totalAvailable. Absent when no comments were dropped and all available comments were loaded."New value: +"Traversal context: counts of deleted/dead comments dropped, the IDs that failed to load and how to retry them, then what stopped the traversal and how to continue — nextCursor for a count, size, or rate-limit stop, or a larger depth or a comment id as itemId for a depth cut. Absent when nothing was dropped, failed, or left unread."
    • changedOutput schema / properties / totalAvailable / description
      Previous value: -"Total comment count from the root item. If totalLoaded < totalAvailable, raise maxComments (and depth, if you want nested replies) and call again."New value: +"HN's total comment count for the root (descendants), which also counts dead and deleted comments. Absent for comment and job roots."
    • changedOutput schema / properties / totalLoaded / description
      Previous value: -"Number of comments actually fetched and included."New value: +"Number of comments in this response (this page, when paging with cursor)."
    • changedOutput schema / properties / truncated / description
      Previous value: -"True when maxComments stopped the traversal while comments remained. Absent when every available comment was loaded, even at exactly maxComments."New value: +"True when comments remain unread: reachable through nextCursor (truncationReason count, size, or rate_limited), or below the depth limit (depth). Absent on a terminal page — including a thread that loads in full at exactly maxComments."
    • addedOutput schema / properties / truncationReason
      Added value: +{
      +  "description": "Why the traversal stopped short: count = maxComments (or the 1,000-item ceiling per call) was reached; size = the 64,000-byte response budget was reached; rate_limited = the HN API throttled the fetches; depth = replies lie below the depth limit, which nextCursor does not reach — raise depth or pass a comment id as itemId. When a cursor reason and a depth cut both apply, the cursor reason is reported.",
      +  "enum": [
      +    "count",
      +    "size",
      +    "depth",
      +    "rate_limited"
      +  ],
      +  "type": "string"
      +}
  2. Changed2 schema fields changed
    • changedOutput schema / properties / notice / description
      Previous value: -"Truncation context: counts of deleted/dead comments dropped during traversal, or pagination hint when totalLoaded < totalAvailable. Absent when no comments were dropped and all available comments were loaded."New value: +"Truncation context: counts of deleted/dead comments dropped during traversal, then either how to get past the maxComments cap when it stopped the traversal, or a raise-maxComments-or-depth hint when totalLoaded < totalAvailable. Absent when no comments were dropped and all available comments were loaded."
    • changedOutput schema / properties / truncated / description
      Previous value: -"True when the comment list was capped by maxComments."New value: +"True when maxComments stopped the traversal while comments remained. Absent when every available comment was loaded, even at exactly maxComments."
  3. Changed6 schema fields changed
    • changedInput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • addedInput schema / additionalProperties
      Added value: +false
    • changedOutput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • addedOutput schema / anyOf
      Added value: +[
      +  {
      +    "not": {
      +      "required": [
      +        "error"
      +      ]
      +    },
      +    "required": [
      +      "item",
      +      "comments",
      +      "totalLoaded"
      +    ]
      +  },
      +  {
      +    "required": [
      +      "error"
      +    ]
      +  }
      +]
    • addedOutput schema / properties / error
      Added value: +{
      +  "additionalProperties": {},
      +  "description": "Present when the call failed. Absent on success.",
      +  "properties": {
      +    "code": {
      +      "description": "JSON-RPC error code for this failure.",
      +      "maximum": 9007199254740991,
      +      "minimum": -9007199254740991,
      +      "type": "integer"
      +    },
      +    "data": {
      +      "additionalProperties": {},
      +      "properties": {
      +        "reason": {
      +          "description": "Machine-readable failure mode. Declared by this tool: `item_not_found`: HN reports no item exists for the given itemId. `upstream_rejected`: The HN API answered with a 4xx status other than 429 — it rejected the request as built. `upstream_rate_limited`: The HN API answered with HTTP 429. `upstream_unavailable`: The HN API answered with a 5xx status. `upstream_html`: The HN API served an HTML error page with a 200 status, which it does under rate limiting or maintenance. `upstream_malformed`: The HN API answered with a 200 status and a body that is not JSON. Other values are possible when a failure originates below the handler.",
      +          "examples": [
      +            "item_not_found",
      +            "upstream_rejected",
      +            "upstream_rate_limited",
      +            "upstream_unavailable",
      +            "upstream_html",
      +            "upstream_malformed"
      +          ],
      +          "type": "string"
      +        },
      +        "recovery": {
      +          "additionalProperties": {},
      +          "description": "Actionable next step for the caller.",
      +          "properties": {
      +            "hint": {
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "hint"
      +          ],
      +          "type": "object"
      +        },
      +        "retryable": {
      +          "description": "Whether retrying may succeed.",
      +          "type": "boolean"
      +        }
      +      },
      +      "type": "object"
      +    },
      +    "message": {
      +      "description": "Human-readable description of what went wrong.",
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "code",
      +    "message"
      +  ],
      +  "type": "object"
      +}
    • removedOutput schema / required
      Removed value: -[
      -  "item",
      -  "comments",
      -  "totalLoaded"
      -]
  4. Changed5 schema fields changed
    • changedInput schema / properties / depth / type
      Previous value: -"number"New value: +"integer"
    • addedInput schema / properties / itemId / maximum
      Added value: +9007199254740991
    • addedInput schema / properties / itemId / minimum
      Added value: +-9007199254740991
    • changedInput schema / properties / itemId / type
      Previous value: -"number"New value: +"integer"
    • changedInput schema / properties / maxComments / type
      Previous value: -"number"New value: +"integer"
  5. Changed3 schema fields changed
    • addedOutput schema / properties / cap
      Added value: +{
      +  "description": "The maxComments cap that was applied.",
      +  "type": "number"
      +}
    • addedOutput schema / properties / shown
      Added value: +{
      +  "description": "Number of comments returned.",
      +  "type": "number"
      +}
    • addedOutput schema / properties / truncated
      Added value: +{
      +  "description": "True when the comment list was capped by maxComments.",
      +  "type": "boolean"
      +}
  6. Changed2 schema fields changed
    • addedOutput schema / properties / notice
      Added value: +{
      +  "description": "Truncation context: counts of deleted/dead comments dropped during traversal, or pagination hint when totalLoaded < totalAvailable. Absent when no comments were dropped and all available comments were loaded.",
      +  "type": "string"
      +}
    • removedOutput schema / properties / omitted
      Removed value: -{
      -  "additionalProperties": false,
      -  "description": "Counts of comments dropped during BFS traversal. Present only when at least one comment was dropped, so the caller can tell when a thread view is partial due to moderation rather than depth/maxComments limits. Absence means no moderation truncation.",
      -  "properties": {
      -    "dead": {
      -      "description": "Count of comments dropped because HN flagged them dead (autoflagged).",
      -      "type": "number"
      -    },
      -    "deleted": {
      -      "description": "Count of comments dropped because HN flagged them deleted (author/mod removal).",
      -      "type": "number"
      -    }
      -  },
      -  "required": [
      -    "deleted",
      -    "dead"
      -  ],
      -  "type": "object"
      -}
  7. Changed2 schema fields changed
    • addedOutput schema / properties / comments / items / properties / isOp
      Added value: +{
      +  "const": true,
      +  "description": "Present and `true` when the comment author matches the root item author (OP replying within their own thread). Omitted otherwise — including when either author is missing. Most threads carry no OP replies, so absence is the common case; treat missing as \"not OP\" rather than unknown.",
      +  "type": "boolean"
      +}
    • addedOutput schema / properties / omitted
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "Counts of comments dropped during BFS traversal. Present only when at least one comment was dropped, so the caller can tell when a thread view is partial due to moderation rather than depth/maxComments limits. Absence means no moderation truncation.",
      +  "properties": {
      +    "dead": {
      +      "description": "Count of comments dropped because HN flagged them dead (autoflagged).",
      +      "type": "number"
      +    },
      +    "deleted": {
      +      "description": "Count of comments dropped because HN flagged them deleted (author/mod removal).",
      +      "type": "number"
      +    }
      +  },
      +  "required": [
      +    "deleted",
      +    "dead"
      +  ],
      +  "type": "object"
      +}
  8. Changed2 schema fields changed
    • changedInput schema / properties / depth / description
      Previous value: -"How many levels of replies to resolve. 0 = just the item, no comments. 1 = direct replies only. Popular stories often have more top-level comments than maxComments — to see nesting, raise maxComments together with depth, or call again on a specific commentId to drill into a subtree."New value: +"How many levels of replies to resolve. 0 = just the item, no comments. 1 = direct replies only. Popular stories often have more top-level comments than maxComments — to see nesting, raise maxComments together with depth, or call again with a specific comment's itemId to drill into a subtree."
    • changedOutput schema / properties / comments / description
      Previous value: -"Flat comment list ordered by ranked BFS traversal. Use depth/parentId to reconstruct nesting."New value: +"Flat comment list ordered breadth-first by rank: highest-ranked top-level comments first, then their replies. Use depth/parentId to reconstruct nesting."
  9. Changed4 schema fields changed
    • changedInput schema / properties / depth / description
      Previous value: -"How many levels of replies to resolve. 0 = just the item, no comments. 1 = direct replies only. Deeper threads on popular stories can be very large — start with 2-3 and go deeper if needed."New value: +"How many levels of replies to resolve. 0 = just the item, no comments. 1 = direct replies only. Popular stories often have more top-level comments than maxComments — to see nesting, raise maxComments together with depth, or call again on a specific commentId to drill into a subtree."
    • changedInput schema / properties / maxComments / description
      Previous value: -"Maximum total comments to include across all depth levels. Traversal stops when this limit is reached. Comments are resolved breadth-first by HN ranking."New value: +"Maximum total comments to include across all depth levels. Highest-ranked top-level comments resolve first; replies fill in only after the level above is exhausted."
    • changedOutput schema / properties / item / properties / type / description
      Previous value: -"Item type."New value: +"Item type: story | comment | job | poll | pollopt."
    • changedOutput schema / properties / totalAvailable / description
      Previous value: -"Total comment count from the root item (descendants field). If totalLoaded < totalAvailable, increase maxComments or depth to see more."New value: +"Total comment count from the root item. If totalLoaded < totalAvailable, raise maxComments (and depth, if you want nested replies) and call again."
  10. Changed1 schema field changed
    • addedOutput schema / properties / comments / items / description
      Added value: +"A single comment in the thread with its tree position."
  11. First observed

TDQS

A4.3/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true, and the description adds useful behavioral context beyond that: recursive comment resolution, depth-based behavior, and pagination through nextCursor. This meaningfully informs an agent about traversal and long-thread handling.

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

Conciseness5/5

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

Three concise sentences with no filler. The primary function is front-loaded, and the key edge cases (depth 0, pagination) are stated clearly and economically.

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

Completeness5/5

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

With a rich input schema, an output schema, and a readOnly annotation, the description covers the essential behavioral nuances: recursive threading, depth-0 lookup, and cursor-based pagination. Nothing critical is missing for an agent to correctly invoke the tool.

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?

Schema description coverage is 100%, so the baseline is 3. The description adds some extra value by explicitly mentioning depth 0 and the nextCursor continuation, but the schema already fully documents all parameters, including depth semantics and cursor constraints.

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

Purpose5/5

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

The description states a specific verb and resource: 'Get an item and its comment tree as a threaded discussion,' with recursive child resolution. This clearly distinguishes it from sibling tools like hn_get_stories or hn_get_user, which serve different resources and purposes.

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

Usage Guidelines4/5

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

The description offers clear usage context, specifying that depth 0 performs an item-only lookup and that long threads are paginated via nextCursor. It does not explicitly contrast with sibling tools or state when not to use this tool, but the unique resource and behavior make the intended use clear.

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

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.