hn-mcp-server
Server Details
Browse Hacker News feeds, threads, and user profiles with full-text search.
- Status
- Healthy
- Uptime
- 100.0% over 44 days
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-11-25
- URL
- Repository
- cyanheads/hn-mcp-server
- GitHub Stars
- 4
- Server Listing
- @cyanheads/hn-mcp-server
TDQS
Scored across 4 tools
Each tool targets a distinct resource: stories feed, item/thread, user profile, and search. There is no overlap in purpose, making selection unambiguous.
All tools follow a consistent 'hn_' prefix with a verb_noun pattern (get_stories, get_thread, get_user, search_content). The naming is predictable and clean.
With 4 tools, the server is well-scoped for a read-only Hacker News access layer. Each tool serves a necessary function without bloat or minimalism.
The tool set covers the core read operations: listing stories, retrieving individual threads, fetching user profiles, and searching content. No obvious gaps exist for a read-only HN server.
Available Tools
4 toolshn_get_storiesHn Get StoriesARead-onlyInspect
Fetch stories from an HN feed (top, new, best, ask, show, jobs), with title, URL, score, author, and comment count for each story.
| Name | Required | Description | Default |
|---|---|---|---|
| feed | Yes | Which HN feed to fetch. "top" includes jobs. "ask" and "show" are Ask HN / Show HN posts. | |
| count | No | Number of stories to return. Larger counts take longer. | |
| offset | No | Number of stories to skip from the start of the feed. Use with count for pagination. |
Output Schema
| Name | Required | Description |
|---|---|---|
| cap | No | The count cap that was applied. |
| feed | No | Which feed was fetched. |
| error | No | Present when the call failed. Absent on success. |
| shown | No | Number of stories returned on this page. |
| total | No | Total items in the feed (up to 500 for top/new/best, 200 for ask/show/jobs). |
| notice | No | Agent guidance: the offset to pass for the next page while more stories remain, the IDs that failed to load and how to retry them, or why a page came back empty — offset past the end of the feed, an empty feed, or every item on the page deleted or flagged. Absent on the last page of a non-empty result with no failed IDs. |
| offset | No | Offset that was applied to this page. |
| hasMore | No | Whether more stories are available beyond this page. |
| stories | No | Stories from the feed, ordered by HN ranking. |
| failedIds | No | IDs on this page whose fetch failed after retries. They are not deleted or missing and may load on a later call: retry the page with the same offset, or pass an ID to hn_get_thread to fetch that story alone. Absent when every item on the page loaded. |
| truncated | No | True when more stories remain beyond this page (hasMore). Absent on the last page of the feed. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, and the description does not contradict this. The description adds no new behavioral context beyond the annotation (e.g., rate limits, auth, or side effects). Given the annotation covers safety, the description's contribution is minimal, so a 3 is appropriate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence that front-loads the core action and lists key output fields. No wasted words; perfectly concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity, an output schema (not shown) documents return values, and annotations cover safety, the description is adequate. It could mention pagination behavior, but the schema already documents offset and count for that. No critical missing context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% — all three parameters (feed, count, offset) are fully described in the schema. The tool description does not add any semantic detail beyond the schema, so it earns the baseline score of 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Fetch') and resource ('stories from an HN feed'), and lists the feed types and returned fields. It clearly distinguishes this from siblings like hn_get_thread or hn_get_user, which target different entities.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly states the context (fetching feed stories) but does not explicitly mention alternatives or when not to use it. However, the tool's scope is self-evident given the named feed types and fields, providing clear context without exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
hn_get_threadHn Get ThreadARead-onlyInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| depth | No | 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. | |
| cursor | No | 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. | |
| itemId | Yes | ID of the story, comment, job, poll, or poll option to fetch the thread for. | |
| maxComments | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
| cap | No | The maxComments cap that was applied. |
| item | No | The root item: a story, comment, job, poll, or poll option. |
| error | No | Present when the call failed. Absent on success. |
| shown | No | Number of comments returned. |
| notice | No | 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. |
| comments | No | 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. |
| failedIds | No | 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. |
| truncated | No | 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. |
| nextCursor | No | 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. |
| totalLoaded | No | Number of comments in this response (this page, when paging with cursor). |
| totalAvailable | No | HN's total comment count for the root (descendants), which also counts dead and deleted comments. Absent for comment and job roots. |
| truncationReason | No | 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. |
TDQS
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.
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.
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.
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.
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.
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.
hn_get_userHn Get UserARead-onlyInspect
Get an HN user profile with karma, about, and optionally their most recent submissions resolved into full items.
| Name | Required | Description | Default |
|---|---|---|---|
| username | Yes | HN username. Case-sensitive. Trimmed; blank or whitespace-only input is rejected. | |
| submissionCount | No | Page size — how many submissions to resolve per call. Only used when includeSubmissions is true. | |
| submissionOffset | No | How many submissions to skip before resolving, counting back from the most recent. Use with submissionCount to page through a long history: request offset 0, then offset submissionCount, and so on. The enrichment block echoes submissionOffset and, when more remain, the offset to send next. Only used when includeSubmissions is true. | |
| includeSubmissions | No | Resolve the user's most recent submissions into full items. Without this, only the submission count is available. |
Output Schema
| Name | Required | Description |
|---|---|---|
| cap | No | The submissionCount cap that was applied. |
| user | No | User profile. |
| error | No | Present when the call failed. Absent on success. |
| shown | No | Number of submissions returned. |
| notice | No | Pagination context — which window of the history this page covers and the submissionOffset to send next, the submission IDs that failed to load and how to retry them, or a warning that the offset is past the end. Absent when the page reaches the end of the history with no failed IDs, or when no submissions were resolved. |
| failedIds | No | Submission IDs in this window whose fetch failed after retries. They are not deleted or missing and may load on a later call: retry with the same submissionOffset, or pass an ID to hn_get_thread to fetch that item alone. Absent when every submission in the window loaded. |
| truncated | No | True when submissions remain beyond this page. |
| submissions | No | One page of submissions, most recent first, starting at submissionOffset. Absent when includeSubmissions is false or the user has never submitted. Empty when the page holds no live items — either the offset is past the end, or every item in the window was deleted, flagged, or failed to load (failedIds lists the failures). |
| submissionOffset | No | The offset this page started at. Absent when includeSubmissions is false or the user has never submitted. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so the safety profile is covered. The description adds a useful behavioral detail ('optionally ... resolved into full items') but does not discuss pagination behavior, rate limits, or what happens when a username is invalid; pagination is left to the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single front-loaded sentence that moves from the main purpose to the optional enhancement. Every word earns its place; there is no fluff or repetition of schema field definitions.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is sufficient for a read-only user-profile tool with a rich input schema and an output schema present. It omits explicit guidance on when to resolve submissions versus when not to, but the schema's parameter descriptions fill that gap adequately.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the schema already explains username casing, page size, paging offsets, and includeSubmissions semantics. The description's mention of 'optionally' only faintly echoes the includeSubmissions parameter and adds no new parameter-level meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description starts with a specific verb and resource: 'Get an HN user profile' and names the exact fields returned (karma, about, optionally resolved submissions). This clearly separates it from sibling tools focused on stories, threads, and content search.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'Get an HN user profile' implies this is the tool for user-profile lookups, but it never states when to prefer it over alternatives or when to enable includeSubmissions. No explicit exclusions or alternative routing are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
hn_search_contentHn Search ContentARead-onlyInspect
Search Hacker News stories, comments, polls, and jobs via Algolia — by keyword, by filters alone, or both. Filterable by content type, author, parent story, date range, and minimum points.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number for pagination (0-indexed). | |
| sort | No | Sort order. "relevance" for best match, "date" for most recent first. | relevance |
| tags | No | Filter results by content type: "story", "comment", "poll", or "job", or the story subsets "ask_hn", "show_hn", and "front_page". Omit to search all types. | |
| view | No | How much of each hit to return. "full" includes every field. "compact" omits the two body-text fields — `text` and `highlights.text` — which together can repeat a long comment twice per hit; everything else (id, title, url, domain, author, points, comment count, timestamp, parent story, title highlight, matchedWords) is unchanged. Use "compact" to scan many results, then pass a hit id to hn_get_thread to read the body you skipped. | full |
| count | No | Number of results to return. | |
| query | No | Search terms. Supports simple keywords — Algolia handles stemming and relevance. Trimmed before searching; blank or whitespace-only input is rejected. Omit for a filter-only search, which needs at least one of tags, author, storyId, minPoints, or a dateRange bound. | |
| author | No | Filter results to a specific author. Useful for finding a user's posts on a topic (hn_get_user only shows recent submissions). Trimmed before filtering; omit the field to search all authors rather than passing a blank string. | |
| storyId | No | Restrict results to one discussion: the id of a story or poll root, combined with the other filters. Pair with tags "comment" to search within a thread. Take it from hits[].storyId or the root item of hn_get_thread — a comment id matches nothing. | |
| dateRange | No | Filter to a creation-time window with a start, an end, or both. An empty object is rejected — omit dateRange instead. | |
| minPoints | No | Minimum score. Applies to stories and polls, including the ask_hn, show_hn, and front_page subsets. Comments and jobs carry no points in the search index, so any minPoints excludes them — combining it with tags "comment" or "job" is rejected. |
Output Schema
| Name | Required | Description |
|---|---|---|
| cap | No | The count cap that was applied. |
| hits | No | Search results ranked by sort order. |
| page | No | Current page number (0-indexed). |
| error | No | Present when the call failed. Absent on success. |
| query | No | The query that was searched. Absent for a filter-only search. |
| shown | No | Number of hits returned. |
| notice | No | Agent guidance: the next page to request while more pages remain, the last valid page when the requested page is past the end, or the filters to relax when a first page comes back empty. Absent on the last page of a non-empty result. |
| totalHits | No | Total matching results across all pages. |
| truncated | No | True when more pages remain after this one (page + 1 < totalPages). Absent on the last page Algolia serves. |
| totalPages | No | Number of pages Algolia will actually serve for this query. Not derived from totalHits — broad queries report a totalHits far larger than the reachable page range, so paginate against this value. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint=true, so the description carries a lower burden. It adds no destructive/auth/rate-limit caveats and does not disclose behavioral quirks beyond the searchable scope; deeper constraints like exclusive date bounds and minPoints excluding comments/jobs are documented in the schema, not the description. Adequate, but not additive beyond the annotation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the verb and object, and every phrase earns its place. It summarizes the search modes and filter categories without repeating schema details or adding filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex tool with 10 parameters, nested objects, and an output schema, the overall definition is complete: parameter descriptions cover edge cases such as empty dateRange rejection and minPoints incompatibility, and the output schema removes the need to describe return values. The main description is a solid high-level summary, though explicit sibling-tool selection is left to schema cross-references.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and each parameter already has a rich description including trimming, exclusivity, enums, defaults, and edge-case behavior. The main description only restates the filterable dimensions at a high level and adds no syntax or constraint details beyond what the schema provides, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the action ('Search'), the resource ('Hacker News stories, comments, polls, and jobs'), the mechanism ('via Algolia'), and both usage modes (keyword, filters, or both). This clearly distinguishes it from the sibling get tools, which retrieve specific items rather than search across content.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description conveys when to use the tool—when searching HN by keyword and/or filters—but it does not explicitly state when not to use it or when to prefer a sibling tool. The only cross-tool routing appears inside the view parameter ('pass a hit id to hn_get_thread'), not in the main description, so usage guidance is implied rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
1 tool update
- Changed
hn_search_content2 fields changed- changed
Output schema / properties / hits / items / properties / highlights / properties / text / descriptionPrevious value: -"Body snippet (comment_text or story_text) with matched terms wrapped in `<em>…</em>`. Absent when the body did not match, and always absent under view \"compact\" — matchedWords still lists what matched."New value: +"Body snippet (comment_text or story_text), HTML stripped, with matched terms wrapped in `<em>…</em>`. A literal `<em>` typed into the body is indistinguishable from a marker. Absent when the body did not match, and always absent under view \"compact\" — matchedWords still lists what matched." - changed
Output schema / properties / hits / items / properties / highlights / properties / title / descriptionPrevious value: -"Title snippet with matched terms wrapped in `<em>…</em>`. Absent when the title did not match."New value: +"Title snippet with matched terms wrapped in `<em>…</em>`. Titles are not HTML, though some arrive entity-encoded; entities are decoded and no tags are stripped, so a literal `<em>` in the title is indistinguishable from a marker. Absent when the title did not match."
3 tool updates
- Changed
hn_get_stories2 fields changed- added
Output schema / properties / failedIdsAdded value: +{ + "description": "IDs on this page whose fetch failed after retries. They are not deleted or missing and may load on a later call: retry the page with the same offset, or pass an ID to hn_get_thread to fetch that story alone. Absent when every item on the page loaded.", + "items": { + "type": "number" + }, + "type": "array" +} - changed
Output schema / properties / notice / descriptionPrevious value: -"Agent guidance: the offset to pass for the next page while more stories remain, or why a page came back empty — offset past the end of the feed, an empty feed, or every item on the page deleted or flagged. Absent on the last page of a non-empty result."New value: +"Agent guidance: the offset to pass for the next page while more stories remain, the IDs that failed to load and how to retry them, or why a page came back empty — offset past the end of the feed, an empty feed, or every item on the page deleted or flagged. Absent on the last page of a non-empty result with no failed IDs."
- Changed
hn_get_thread22 fields changed- added
Input schema / properties / cursorAdded 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" +} - changed
Input schema / properties / depth / descriptionPrevious 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." - changed
Input schema / properties / itemId / descriptionPrevious 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." - changed
Input schema / properties / maxComments / descriptionPrevious 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." - changed
Output schema / properties / comments / descriptionPrevious 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." - changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious 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." - changed
Output schema / properties / error / properties / data / properties / reason / examplesPrevious 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" +] - added
Output schema / properties / failedIdsAdded 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" +} - changed
Output schema / properties / item / descriptionPrevious value: -"The root item (story, comment, or poll)."New value: +"The root item: a story, comment, job, poll, or poll option." - added
Output schema / properties / item / properties / deadAdded value: +{ + "const": true, + "description": "Present and `true` when the root is dead (flagged or killed); its replies are still walked. Omitted otherwise.", + "type": "boolean" +} - added
Output schema / properties / item / properties / deletedAdded 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" +} - added
Output schema / properties / item / properties / optionsAdded 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" +} - added
Output schema / properties / item / properties / parentAdded 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" +} - added
Output schema / properties / item / properties / partsAdded value: +{ + "description": "For a poll root, its option IDs in HN order.", + "items": { + "type": "number" + }, + "type": "array" +} - added
Output schema / properties / item / properties / pollAdded value: +{ + "description": "For a poll-option root, the ID of its poll.", + "type": "number" +} - changed
Output schema / properties / item / properties / title / descriptionPrevious value: -"Story/job title."New value: +"Story/job/poll title." - added
Output schema / properties / nextCursorAdded 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" +} - changed
Output schema / properties / notice / descriptionPrevious 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." - changed
Output schema / properties / totalAvailable / descriptionPrevious 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." - changed
Output schema / properties / totalLoaded / descriptionPrevious value: -"Number of comments actually fetched and included."New value: +"Number of comments in this response (this page, when paging with cursor)." - changed
Output schema / properties / truncated / descriptionPrevious 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." - added
Output schema / properties / truncationReasonAdded 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" +}
- Changed
hn_get_user7 fields changed- added
Output schema / properties / failedIdsAdded value: +{ + "description": "Submission IDs in this window whose fetch failed after retries. They are not deleted or missing and may load on a later call: retry with the same submissionOffset, or pass an ID to hn_get_thread to fetch that item alone. Absent when every submission in the window loaded.", + "items": { + "type": "number" + }, + "type": "array" +} - changed
Output schema / properties / notice / descriptionPrevious value: -"Pagination context — which window of the history this page covers and the submissionOffset to send next, or a warning that the offset is past the end. Absent when the page reaches the end of the history, or when no submissions were resolved."New value: +"Pagination context — which window of the history this page covers and the submissionOffset to send next, the submission IDs that failed to load and how to retry them, or a warning that the offset is past the end. Absent when the page reaches the end of the history with no failed IDs, or when no submissions were resolved." - changed
Output schema / properties / submissions / descriptionPrevious value: -"One page of submissions, most recent first, starting at submissionOffset. Absent when includeSubmissions is false or the user has never submitted. Empty when the page holds no live items — either the offset is past the end, or every item in the window was deleted or flagged."New value: +"One page of submissions, most recent first, starting at submissionOffset. Absent when includeSubmissions is false or the user has never submitted. Empty when the page holds no live items — either the offset is past the end, or every item in the window was deleted, flagged, or failed to load (failedIds lists the failures)." - changed
Output schema / properties / submissions / items / descriptionPrevious value: -"A single submission by the user (story, comment, job, or poll)."New value: +"A single submission by the user (story, comment, job, poll, or poll option)." - added
Output schema / properties / submissions / items / properties / parentAdded value: +{ + "description": "For a comment, the ID of the story or comment it replied to — pass it to hn_get_thread for the context.", + "type": "number" +} - added
Output schema / properties / submissions / items / properties / pollAdded value: +{ + "description": "For a poll option, the ID of its poll.", + "type": "number" +} - changed
Output schema / properties / submissions / items / properties / type / descriptionPrevious value: -"Item type (story, comment, job, poll)."New value: +"Item type (story, comment, job, poll, pollopt)."
3 tool updates
- Changed
hn_get_stories2 fields changed- changed
Output schema / properties / notice / descriptionPrevious value: -"Recovery hint when a page is empty — e.g. offset past end of feed or feed has no items. Absent on non-empty result pages."New value: +"Agent guidance: the offset to pass for the next page while more stories remain, or why a page came back empty — offset past the end of the feed, an empty feed, or every item on the page deleted or flagged. Absent on the last page of a non-empty result." - changed
Output schema / properties / truncated / descriptionPrevious value: -"True when the feed was capped by the count parameter."New value: +"True when more stories remain beyond this page (hasMore). Absent on the last page of the feed."
- Changed
hn_get_thread2 fields changed- changed
Output schema / properties / notice / descriptionPrevious 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." - changed
Output schema / properties / truncated / descriptionPrevious 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."
- Changed
hn_search_content19 fields changed- changed
Input schema / properties / dateRange / descriptionPrevious value: -"Filter to a date window. Useful for finding discussions about recent events."New value: +"Filter to a creation-time window with a start, an end, or both. An empty object is rejected — omit dateRange instead." - changed
Input schema / properties / dateRange / properties / end / descriptionPrevious value: -"End date (ISO 8601). Results created before this date."New value: +"Exclusive upper bound — only items created strictly before this instant match. Same formats and UTC reading as start, and must be later than start. A date-only end excludes that whole UTC day: to include it, pass the next day or a full timestamp." - added
Input schema / properties / dateRange / properties / end / patternAdded value: +"^(\\d{4})(?:-(\\d{2})(?:-(\\d{2})(?:T(\\d{2}):(\\d{2})(?::(\\d{2})(?:\\.\\d{1,3})?)?(?:Z|[+-](\\d{2}):(\\d{2}))?)?)?)?$" - changed
Input schema / properties / dateRange / properties / start / descriptionPrevious value: -"Start date (ISO 8601). Results created after this date."New value: +"Exclusive lower bound — only items created strictly after this instant match. ISO 8601: YYYY, YYYY-MM, YYYY-MM-DD, or YYYY-MM-DDThh:mm[:ss[.sss]] with an optional Z or ±hh:mm offset. Reduced and date-only forms mean UTC midnight at the start of that period; a date-time without an offset is read as UTC." - added
Input schema / properties / dateRange / properties / start / patternAdded value: +"^(\\d{4})(?:-(\\d{2})(?:-(\\d{2})(?:T(\\d{2}):(\\d{2})(?::(\\d{2})(?:\\.\\d{1,3})?)?(?:Z|[+-](\\d{2}):(\\d{2}))?)?)?)?$" - changed
Input schema / properties / minPoints / descriptionPrevious value: -"Minimum score/points. Filters out low-engagement content."New value: +"Minimum score. Applies to stories and polls, including the ask_hn, show_hn, and front_page subsets. Comments and jobs carry no points in the search index, so any minPoints excludes them — combining it with tags \"comment\" or \"job\" is rejected." - changed
Input schema / properties / query / descriptionPrevious value: -"Search terms. Supports simple keywords — Algolia handles stemming and relevance. Trimmed before searching; blank or whitespace-only input is rejected."New value: +"Search terms. Supports simple keywords — Algolia handles stemming and relevance. Trimmed before searching; blank or whitespace-only input is rejected. Omit for a filter-only search, which needs at least one of tags, author, storyId, minPoints, or a dateRange bound." - added
Input schema / properties / storyIdAdded value: +{ + "description": "Restrict results to one discussion: the id of a story or poll root, combined with the other filters. Pair with tags \"comment\" to search within a thread. Take it from hits[].storyId or the root item of hn_get_thread — a comment id matches nothing.", + "exclusiveMinimum": 0, + "maximum": 9007199254740991, + "type": "integer" +} - changed
Input schema / properties / tags / descriptionPrevious value: -"Filter results by content type. Omit to search all types."New value: +"Filter results by content type: \"story\", \"comment\", \"poll\", or \"job\", or the story subsets \"ask_hn\", \"show_hn\", and \"front_page\". Omit to search all types." - changed
Input schema / properties / tags / enumPrevious value: -[ - "story", - "comment", - "ask_hn", - "show_hn", - "front_page" -]New value: +[ + "story", + "comment", + "poll", + "job", + "ask_hn", + "show_hn", + "front_page" +] - removed
Input schema / requiredRemoved value: -[ - "query" -] - changed
Output schema / anyOfPrevious value: -[ - { - "not": { - "required": [ - "error" - ] - }, - "required": [ - "hits", - "query", - "totalHits", - "page", - "totalPages" - ] - }, - { - "required": [ - "error" - ] - } -]New value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "hits", + "totalHits", + "page", + "totalPages" + ] + }, + { + "required": [ + "error" + ] + } +] - changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode. Declared by this tool: `upstream_rejected`: Algolia answered with a 4xx status other than 429 — it rejected the request as built. `upstream_rate_limited`: Algolia answered with HTTP 429. `upstream_unavailable`: Algolia answered with a 5xx status. `upstream_html`: Algolia served an HTML error page with a 200 status, which it does under rate limiting or maintenance. `upstream_malformed`: Algolia 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: `missing_query_or_filter`: Neither a query nor any filter was supplied, so there is nothing to search by. `invalid_date_range`: dateRange was supplied with neither bound, or with start not before end. `min_points_unscored_type`: minPoints was combined with tags \"comment\" or \"job\", record types Algolia stores without points. `upstream_rejected`: Algolia answered with a 4xx status other than 429 — it rejected the request as built. `upstream_rate_limited`: Algolia answered with HTTP 429. `upstream_unavailable`: Algolia answered with a 5xx status. `upstream_html`: Algolia served an HTML error page with a 200 status, which it does under rate limiting or maintenance. `upstream_malformed`: Algolia answered with a 200 status and a body that is not JSON. Other values are possible when a failure originates below the handler." - changed
Output schema / properties / error / properties / data / properties / reason / examplesPrevious value: -[ - "upstream_rejected", - "upstream_rate_limited", - "upstream_unavailable", - "upstream_html", - "upstream_malformed" -]New value: +[ + "missing_query_or_filter", + "invalid_date_range", + "min_points_unscored_type", + "upstream_rejected", + "upstream_rate_limited", + "upstream_unavailable", + "upstream_html", + "upstream_malformed" +] - changed
Output schema / properties / hits / items / descriptionPrevious value: -"A single Algolia search hit (story or comment)."New value: +"A single Algolia search hit (story, comment, poll, or job)." - changed
Output schema / properties / hits / items / properties / title / descriptionPrevious value: -"Story title (present for stories)."New value: +"Item title (present for stories, polls, and jobs)." - changed
Output schema / properties / notice / descriptionPrevious value: -"Recovery hint when results are empty — names the filters applied, for relaxing the search. Absent on non-empty result pages."New value: +"Agent guidance: the next page to request while more pages remain, the last valid page when the requested page is past the end, or the filters to relax when a first page comes back empty. Absent on the last page of a non-empty result." - changed
Output schema / properties / query / descriptionPrevious value: -"The query that was searched."New value: +"The query that was searched. Absent for a filter-only search." - changed
Output schema / properties / truncated / descriptionPrevious value: -"True when the hit list was capped by the count parameter."New value: +"True when more pages remain after this one (page + 1 < totalPages). Absent on the last page Algolia serves."
4 tool updates
- Changed
hn_get_stories6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "stories", + "feed", + "total", + "offset", + "hasMore" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded 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: `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": [ + "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" +} - removed
Output schema / requiredRemoved value: -[ - "stories", - "feed", - "total", - "offset", - "hasMore" -]
- Changed
hn_get_thread6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "item", + "comments", + "totalLoaded" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded 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" +} - removed
Output schema / requiredRemoved value: -[ - "item", - "comments", - "totalLoaded" -]
- Changed
hn_get_user6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "user" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded 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: `user_not_found`: HN reports no user account exists for the given username. `upstream_rejected`: The HN API answered with a 4xx status other than 429 — it rejected the request as built, which a username outside HN’s charset can cause. `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": [ + "user_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" +} - removed
Output schema / requiredRemoved value: -[ - "user" -]
- Changed
hn_search_content6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "hits", + "query", + "totalHits", + "page", + "totalPages" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded 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: `upstream_rejected`: Algolia answered with a 4xx status other than 429 — it rejected the request as built. `upstream_rate_limited`: Algolia answered with HTTP 429. `upstream_unavailable`: Algolia answered with a 5xx status. `upstream_html`: Algolia served an HTML error page with a 200 status, which it does under rate limiting or maintenance. `upstream_malformed`: Algolia answered with a 200 status and a body that is not JSON. Other values are possible when a failure originates below the handler.", + "examples": [ + "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" +} - removed
Output schema / requiredRemoved value: -[ - "hits", - "query", - "totalHits", - "page", - "totalPages" -]
2 tool updates
- Changed
hn_get_user6 fields changed- changed
Input schema / properties / submissionCount / descriptionPrevious value: -"Number of recent submissions to resolve. Only used when includeSubmissions is true."New value: +"Page size — how many submissions to resolve per call. Only used when includeSubmissions is true." - added
Input schema / properties / submissionOffsetAdded value: +{ + "default": 0, + "description": "How many submissions to skip before resolving, counting back from the most recent. Use with submissionCount to page through a long history: request offset 0, then offset submissionCount, and so on. The enrichment block echoes submissionOffset and, when more remain, the offset to send next. Only used when includeSubmissions is true.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" +} - changed
Output schema / properties / notice / descriptionPrevious value: -"Pagination caveat when submissions were truncated. Absent when all submissions fit within the requested count or includeSubmissions is false."New value: +"Pagination context — which window of the history this page covers and the submissionOffset to send next, or a warning that the offset is past the end. Absent when the page reaches the end of the history, or when no submissions were resolved." - added
Output schema / properties / submissionOffsetAdded value: +{ + "description": "The offset this page started at. Absent when includeSubmissions is false or the user has never submitted.", + "type": "number" +} - changed
Output schema / properties / submissions / descriptionPrevious value: -"Recent submissions, most recent first. Only present when includeSubmissions is true."New value: +"One page of submissions, most recent first, starting at submissionOffset. Absent when includeSubmissions is false or the user has never submitted. Empty when the page holds no live items — either the offset is past the end, or every item in the window was deleted or flagged." - changed
Output schema / properties / truncated / descriptionPrevious value: -"True when submissions were capped by submissionCount."New value: +"True when submissions remain beyond this page."
- Changed
hn_search_content3 fields changed- added
Input schema / properties / viewAdded value: +{ + "default": "full", + "description": "How much of each hit to return. \"full\" includes every field. \"compact\" omits the two body-text fields — `text` and `highlights.text` — which together can repeat a long comment twice per hit; everything else (id, title, url, domain, author, points, comment count, timestamp, parent story, title highlight, matchedWords) is unchanged. Use \"compact\" to scan many results, then pass a hit id to hn_get_thread to read the body you skipped.", + "enum": [ + "full", + "compact" + ], + "type": "string" +} - changed
Output schema / properties / hits / items / properties / highlights / properties / text / descriptionPrevious value: -"Body snippet (comment_text or story_text) with matched terms wrapped in `<em>…</em>`. Absent when the body did not match."New value: +"Body snippet (comment_text or story_text) with matched terms wrapped in `<em>…</em>`. Absent when the body did not match, and always absent under view \"compact\" — matchedWords still lists what matched." - changed
Output schema / properties / hits / items / properties / text / descriptionPrevious value: -"Comment or story body text (HTML stripped)."New value: +"Comment or story body text (HTML stripped). Absent when the hit has no body, and always absent under view \"compact\" — call hn_get_thread with this id to read it."
4 tool updates
- Changed
hn_get_stories3 fields changed- changed
Input schema / properties / count / typePrevious value: -"number"New value: +"integer" - added
Input schema / properties / offset / maximumAdded value: +9007199254740991 - changed
Input schema / properties / offset / typePrevious value: -"number"New value: +"integer"
- Changed
hn_get_thread5 fields changed- changed
Input schema / properties / depth / typePrevious value: -"number"New value: +"integer" - added
Input schema / properties / itemId / maximumAdded value: +9007199254740991 - added
Input schema / properties / itemId / minimumAdded value: +-9007199254740991 - changed
Input schema / properties / itemId / typePrevious value: -"number"New value: +"integer" - changed
Input schema / properties / maxComments / typePrevious value: -"number"New value: +"integer"
- Changed
hn_get_user2 fields changed- changed
Input schema / properties / submissionCount / typePrevious value: -"number"New value: +"integer" - changed
Input schema / properties / username / descriptionPrevious value: -"HN username. Case-sensitive."New value: +"HN username. Case-sensitive. Trimmed; blank or whitespace-only input is rejected."
- Changed
hn_search_content10 fields changed- changed
Input schema / properties / author / descriptionPrevious value: -"Filter results to a specific author. Useful for finding a user's posts on a topic (hn_get_user only shows recent submissions)."New value: +"Filter results to a specific author. Useful for finding a user's posts on a topic (hn_get_user only shows recent submissions). Trimmed before filtering; omit the field to search all authors rather than passing a blank string." - added
Input schema / properties / author / minLengthAdded value: +1 - changed
Input schema / properties / count / typePrevious value: -"number"New value: +"integer" - added
Input schema / properties / minPoints / maximumAdded value: +9007199254740991 - changed
Input schema / properties / minPoints / typePrevious value: -"number"New value: +"integer" - added
Input schema / properties / page / maximumAdded value: +9007199254740991 - changed
Input schema / properties / page / typePrevious value: -"number"New value: +"integer" - changed
Input schema / properties / query / descriptionPrevious value: -"Search terms. Supports simple keywords — Algolia handles stemming and relevance."New value: +"Search terms. Supports simple keywords — Algolia handles stemming and relevance. Trimmed before searching; blank or whitespace-only input is rejected." - added
Input schema / properties / query / minLengthAdded value: +1 - changed
Output schema / properties / totalPages / descriptionPrevious value: -"Total pages available."New value: +"Number of pages Algolia will actually serve for this query. Not derived from totalHits — broad queries report a totalHits far larger than the reachable page range, so paginate against this value."
4 tool updates
- Changed
hn_get_stories3 fields changed- added
Output schema / properties / capAdded value: +{ + "description": "The count cap that was applied.", + "type": "number" +} - added
Output schema / properties / shownAdded value: +{ + "description": "Number of stories returned on this page.", + "type": "number" +} - added
Output schema / properties / truncatedAdded value: +{ + "description": "True when the feed was capped by the count parameter.", + "type": "boolean" +}
- Changed
hn_get_thread3 fields changed- added
Output schema / properties / capAdded value: +{ + "description": "The maxComments cap that was applied.", + "type": "number" +} - added
Output schema / properties / shownAdded value: +{ + "description": "Number of comments returned.", + "type": "number" +} - added
Output schema / properties / truncatedAdded value: +{ + "description": "True when the comment list was capped by maxComments.", + "type": "boolean" +}
- Changed
hn_get_user3 fields changed- added
Output schema / properties / capAdded value: +{ + "description": "The submissionCount cap that was applied.", + "type": "number" +} - added
Output schema / properties / shownAdded value: +{ + "description": "Number of submissions returned.", + "type": "number" +} - added
Output schema / properties / truncatedAdded value: +{ + "description": "True when submissions were capped by submissionCount.", + "type": "boolean" +}
- Changed
hn_search_content3 fields changed- added
Output schema / properties / capAdded value: +{ + "description": "The count cap that was applied.", + "type": "number" +} - added
Output schema / properties / shownAdded value: +{ + "description": "Number of hits returned.", + "type": "number" +} - added
Output schema / properties / truncatedAdded value: +{ + "description": "True when the hit list was capped by the count parameter.", + "type": "boolean" +}
1 tool update
- Changed
hn_get_user1 field changed- added
Output schema / properties / noticeAdded value: +{ + "description": "Pagination caveat when submissions were truncated. Absent when all submissions fit within the requested count or includeSubmissions is false.", + "type": "string" +}
3 tool updates
- Changed
hn_get_stories2 fields changed- added
Output schema / properties / noticeAdded value: +{ + "description": "Recovery hint when a page is empty — e.g. offset past end of feed or feed has no items. Absent on non-empty result pages.", + "type": "string" +} - changed
Output schema / properties / offset / descriptionPrevious value: -"Offset that was applied to this page (echoes input.offset)."New value: +"Offset that was applied to this page."
- Changed
hn_get_thread2 fields changed- added
Output schema / properties / noticeAdded 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" +} - removed
Output schema / properties / omittedRemoved 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" -}
- Changed
hn_search_content4 fields changed- removed
Output schema / properties / messageRemoved value: -{ - "description": "Recovery hint when results are empty — names the filters that were applied, for relaxing the search. Absent on non-empty result pages.", - "type": "string" -} - added
Output schema / properties / noticeAdded value: +{ + "description": "Recovery hint when results are empty — names the filters applied, for relaxing the search. Absent on non-empty result pages.", + "type": "string" +} - changed
Output schema / properties / page / descriptionPrevious value: -"Current page number."New value: +"Current page number (0-indexed)." - changed
Output schema / requiredPrevious value: -[ - "hits", - "totalHits", - "page", - "totalPages", - "query" -]New value: +[ + "hits", + "query", + "totalHits", + "page", + "totalPages" +]
3 tool updates
- Changed
hn_get_stories1 field changed- added
Output schema / properties / stories / items / properties / domainAdded value: +{ + "description": "Bare hostname derived from url (e.g. \"github.com\", with leading \"www.\" stripped). Absent when url is missing or unparseable.", + "type": "string" +}
- Changed
hn_get_thread2 fields changed- added
Output schema / properties / comments / items / properties / isOpAdded 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" +} - added
Output schema / properties / omittedAdded 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" +}
- Changed
hn_search_content2 fields changed- added
Output schema / properties / hits / items / properties / domainAdded value: +{ + "description": "Bare hostname derived from url (e.g. \"github.com\", with leading \"www.\" stripped). Absent when url is missing or unparseable.", + "type": "string" +} - added
Output schema / properties / hits / items / properties / highlightsAdded value: +{ + "additionalProperties": false, + "description": "Algolia per-field highlight metadata showing which terms matched and where. Absent when no fields produced a match.", + "properties": { + "matchedWords": { + "description": "Deduplicated union of matched terms across all searchable fields (title, url, author, comment_text, story_text, story_title).", + "items": { + "type": "string" + }, + "type": "array" + }, + "text": { + "description": "Body snippet (comment_text or story_text) with matched terms wrapped in `<em>…</em>`. Absent when the body did not match.", + "type": "string" + }, + "title": { + "description": "Title snippet with matched terms wrapped in `<em>…</em>`. Absent when the title did not match.", + "type": "string" + } + }, + "required": [ + "matchedWords" + ], + "type": "object" +}
Related MCP Connectors
HN front-page, Algolia full-text search, and Show HN launch tracker.
Hacker News MCP — search and retrieve stories from Hacker News
Scrape Hacker News stories, comments and user profiles as clean JSON with points, author…
News search, article lookup, story coverage and save links for hamir's RSS catalogue
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables browsing Hacker News, searching discussions, analyzing users, and tracking tech trends with zero setup required—no API keys or authentication needed.527 npm6MIT
- AlicenseNot gradedqualityBmaintenanceEnables searching and retrieving top stories and individual items from Hacker News, with access to scores, comments, authors, and timestamps.179 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-
- 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.932 npmMIT
Glama MCP Gateway
Add one secure layer between your agents and this server.