Hacker News
The io.b3os/hacker-news pack: 5 actions and 1 trigger with call snippets, fixture outputs, connection setup and error codes, generated from version 1.0.0.
io.b3os/hacker-news 1.0.0 · news, developer-tools, social · MIT
Read Hacker News: the current front page, full-text search over stories and comments (newest first or by relevance), single items with their comment ids, and user profiles. Uses the public Algolia HN Search API and the official Firebase API. Keyless and read-only; no connection needed.
Every call's result carries upstream_status and timing: validate_ms, inject_ms, render_ms, upstream_ms, map_ms and total_ms. upstream is the service's time; the others are B3OS's own (call actions). The snippets below show no timing values, because a fixture records none.
Connection
No credential: a keyless public API. Calls name no connection.
Hosts it reaches: hn.algolia.com, hacker-news.firebaseio.com.
Actions
| Action | Effect | MCP tool | Title |
|---|---|---|---|
get-front-page | read | hacker-news__get-front-page | Get the front page |
search | read | hacker-news__search | Search by relevance |
search-recent | read | hacker-news__search-recent | Search newest first |
get-item | read | hacker-news__get-item | Get an item |
get-user | read | hacker-news__get-user | Get a user |
get-front-page
Get the front page. The stories on the Hacker News front page right now, in Algolia's front-page order, with points, comment counts, links and discussion URLs. Use search-recent for what is new and search for a topic.
Ref io.b3os/hacker-news/get-front-page@1.0.0 · effect read · no connection · MCP tool hacker-news__get-front-page
bashcurl -s https://beta-api.b3os.org/v1/actions/call \ -H "Authorization: Bearer $B3OS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "ref": "io.b3os/hacker-news/get-front-page@1", "input": {"hits_per_page": 3} }'
tsimport { B3OS } from "@b3os/sdk";const b3os = new B3OS();const result = await b3os.actions.call({ ref: "io.b3os/hacker-news/get-front-page@1", input: { hits_per_page: 3 },});console.log(result.output);
pythonfrom b3os import B3OSb3os = B3OS()result = b3os.actions.call({ "ref": "io.b3os/hacker-news/get-front-page@1", "input": {"hits_per_page": 3},})print(result["output"])
json{ "method": "tools/call", "params": { "name": "hacker-news__get-front-page", "arguments": {"hits_per_page": 3} }}
Expose the pack as tools with --packs hacker-news on the local server or ?packs=hacker-news on the remote URL, and the agent calls hacker-news__get-front-page with the action's input. The tool needs no connection. Without exposing the pack, actions_call takes the same input with ref.
Output, labeled fixture: Get the front page (response recorded 2026-10-26). From the bundle's fixtures/get-front-page.json, not a live call.
json{ "stories": [ { "id": "50225695", "title": "We should be more ambitious with the software we build", "url": "https://danluu.com/ambitious/", "hn_url": "https://news.ycombinator.com/item?id=50225695", "author": "ltratt", "points": 782, "comments": 702, "created_at": "2026-10-24T21:47:31Z", "created_at_i": 1792878451, "text": null }, { "id": "50233779", "title": "A 10-year-old CNN outperforms frontier LLMs for skin cancer diagnosis", "url": "https://lynchlab.net/llm-skin-cancer", "hn_url": "https://news.ycombinator.com/item?id=50233779", "author": "sungam", "points": 515, "comments": 229, "created_at": "2026-10-25T17:15:38Z", "created_at_i": 1792948538, "text": null }, { "id": "50234474", "title": "Dolly Parton's Imagination Library", "url": "https://imaginationlibrary.com/", "hn_url": "https://news.ycombinator.com/item?id=50234474", "author": "jumploops", "points": 499, "comments": 88, "created_at": "2026-10-25T18:23:54Z", "created_at_i": 1792952634, "text": "With today's news, I thought I'd share this great program:<p>“When I was growing up in the hills of East Tennessee, I knew my dreams would come true. I know there are children in your community with their own dreams. They dream of becoming a doctor or an inventor or a minister. Who knows, maybe there is a little girl whose dream is to be a writer and singer.<p>The seeds of these dreams are often found in books and the seeds you help plant in your community can grow across the world.”" } ], "total": 30,
The first 40 of 43 lines; the fixture file has the rest.
When the service answers with an error, the call fails with upstream_error and pack_error.code is one of:
pack_error.code | Service status | Retryable | Message |
|---|---|---|---|
rate_limited | 429 | yes | Algolia's HN Search rate limit reached (10,000 requests an hour per IP). |
invalid_request | 400, 422 | no | built from the service's response |
search
Search by relevance. Full-text search over Hacker News ranked by relevance, then points and comment count. Filter by item type, minimum points and creation time; page through with page. Returns stories (or comments, when type is comment) with links and discussion URLs.
Ref io.b3os/hacker-news/search@1.0.0 · effect read · no connection · MCP tool hacker-news__search
bashcurl -s https://beta-api.b3os.org/v1/actions/call \ -H "Authorization: Bearer $B3OS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "ref": "io.b3os/hacker-news/search@1", "input": { "query": "firecracker microvm", "hits_per_page": 3, "min_points": 50 } }'
tsimport { B3OS } from "@b3os/sdk";const b3os = new B3OS();const result = await b3os.actions.call({ ref: "io.b3os/hacker-news/search@1", input: { query: "firecracker microvm", hits_per_page: 3, min_points: 50 },});console.log(result.output);
pythonfrom b3os import B3OSb3os = B3OS()result = b3os.actions.call({ "ref": "io.b3os/hacker-news/search@1", "input": { "query": "firecracker microvm", "hits_per_page": 3, "min_points": 50, },})print(result["output"])
json{ "method": "tools/call", "params": { "name": "hacker-news__search", "arguments": { "query": "firecracker microvm", "hits_per_page": 3, "min_points": 50 } }}
Expose the pack as tools with --packs hacker-news on the local server or ?packs=hacker-news on the remote URL, and the agent calls hacker-news__search with the action's input. The tool needs no connection. Without exposing the pack, actions_call takes the same input with ref.
Output, labeled fixture: Search by relevance (response recorded 2026-10-26). From the bundle's fixtures/search.json, not a live call.
json{ "stories": [ { "id": "49912444", "title": "5x faster Edge Functions: V8 isolates to Firecracker MicroVMs", "url": "https://www.netlify.com/blog/edge-functions-firecracker-microvms/", "hn_url": "https://news.ycombinator.com/item?id=49912444", "author": "jbott", "points": 230, "comments": 109, "created_at": "2026-09-30T18:17:45Z", "created_at_i": 1790792265, "text": null }, { "id": "32767784", "title": "Attacking Firecracker: AWS' MicroVM Monitor Written in Rust", "url": "https://www.graplsecurity.com/post/attacking-firecracker", "hn_url": "https://news.ycombinator.com/item?id=32767784", "author": "pentestercrab", "points": 212, "comments": 29, "created_at": "2022-09-08T16:20:36Z", "created_at_i": 1662654036, "text": null }, { "id": "28893884", "title": "Firecracker MicroVMs", "url": "https://firecracker-microvm.github.io/", "hn_url": "https://news.ycombinator.com/item?id=28893884", "author": "colinprince", "points": 176, "comments": 60, "created_at": "2021-10-17T04:11:41Z", "created_at_i": 1634443901, "text": null } ], "total": 14,
The first 40 of 43 lines; the fixture file has the rest.
When the service answers with an error, the call fails with upstream_error and pack_error.code is one of:
pack_error.code | Service status | Retryable | Message |
|---|---|---|---|
rate_limited | 429 | yes | Algolia's HN Search rate limit reached (10,000 requests an hour per IP). |
invalid_request | 400, 422 | no | built from the service's response |
search-recent
Search newest first. The same search as search, sorted by creation time with the newest first. Use it to watch a topic or to list what was just posted (empty query with type story is the /newest page).
Ref io.b3os/hacker-news/search-recent@1.0.0 · effect read · no connection · MCP tool hacker-news__search-recent
bashcurl -s https://beta-api.b3os.org/v1/actions/call \ -H "Authorization: Bearer $B3OS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "ref": "io.b3os/hacker-news/search-recent@1", "input": {"query": "rust", "hits_per_page": 3} }'
tsimport { B3OS } from "@b3os/sdk";const b3os = new B3OS();const result = await b3os.actions.call({ ref: "io.b3os/hacker-news/search-recent@1", input: { query: "rust", hits_per_page: 3 },});console.log(result.output);
pythonfrom b3os import B3OSb3os = B3OS()result = b3os.actions.call({ "ref": "io.b3os/hacker-news/search-recent@1", "input": {"query": "rust", "hits_per_page": 3},})print(result["output"])
json{ "method": "tools/call", "params": { "name": "hacker-news__search-recent", "arguments": {"query": "rust", "hits_per_page": 3} }}
Expose the pack as tools with --packs hacker-news on the local server or ?packs=hacker-news on the remote URL, and the agent calls hacker-news__search-recent with the action's input. The tool needs no connection. Without exposing the pack, actions_call takes the same input with ref.
Output, labeled fixture: Search newest first (response recorded 2026-10-26). From the bundle's fixtures/search-recent.json, not a live call.
json{ "stories": [ { "id": "50240115", "title": "Ask HN: Did crates.io stop processing new crate publishes?", "url": null, "hn_url": "https://news.ycombinator.com/item?id=50240115", "author": "davvid", "points": 1, "comments": 0, "created_at": "2026-10-26T07:03:21Z", "created_at_i": 1792998201, "text": "For example https://crates.io/crates/saphyr-parser/0.3.2/code was recently published (without any client-side errors) but crates.io says:<p><pre><code> The source code for this version is not available yet.\n\n Archives are built shortly after a version is published. This usually only takes a few seconds, so please try again in a couple of minutes.\n\n</code></pre>\nI've never seen this error before. The same can be seen by this just-published crate (12 minutes ago) says the same thing: https://crates.io/crates/skia-bindings/0.156.0/code<p>Does anyone know what's going on?" }, { "id": "50239988", "title": "Show HN: Skill-spotter, auto detect agent prompts and commands to create skills", "url": "https://github.com/ykisana/skill-spotter", "hn_url": "https://news.ycombinator.com/item?id=50239988", "author": "ykisana", "points": 1, "comments": 0, "created_at": "2026-10-26T06:48:10Z", "created_at_i": 1792997290, "text": "Skill-spotter auto detects commands and prompts you type.\nIt detects variations such as 'push these changes' and 'get these changes pushed'. Using both word comparison and the actual actions you agent performs.<p>It also adds to your Claude.md if that's more applicable than creating a skill.<p>Just saving lots of time if you do repeat prompts." }, { "id": "50239884", "title": "France's Nuclear Forces Bring in Neighbors to Keep Russia in Check", "url": "https://www.wsj.com/world/europe/frances-nuclear-forces-bring-in-neighbors-to-keep-russia-in-check-58b0967d", "hn_url": "https://news.ycombinator.com/item?id=50239884", "author": "JumpCrisscross", "points": 2, "comments": 0, "created_at": "2026-10-26T06:33:35Z", "created_at_i": 1792996415, "text": null } ], "total": 71533,
The first 40 of 43 lines; the fixture file has the rest.
When the service answers with an error, the call fails with upstream_error and pack_error.code is one of:
pack_error.code | Service status | Retryable | Message |
|---|---|---|---|
rate_limited | 429 | yes | Algolia's HN Search rate limit reached (10,000 requests an hour per IP). |
invalid_request | 400, 422 | no | built from the service's response |
get-item
Get an item. One story, comment, job or poll by id from the official API: title, link, text, author, score, time, and the ids of its direct replies (kids, in ranked order). Call it again with a kid id to walk a thread.
Ref io.b3os/hacker-news/get-item@1.0.0 · effect read · no connection · MCP tool hacker-news__get-item
bashcurl -s https://beta-api.b3os.org/v1/actions/call \ -H "Authorization: Bearer $B3OS_API_KEY" \ -H "Content-Type: application/json" \ -d '{"ref": "io.b3os/hacker-news/get-item@1", "input": {"id": 8863}}'
tsimport { B3OS } from "@b3os/sdk";const b3os = new B3OS();const result = await b3os.actions.call({ ref: "io.b3os/hacker-news/get-item@1", input: { id: 8863 } });console.log(result.output);
pythonfrom b3os import B3OSb3os = B3OS()result = b3os.actions.call({"ref": "io.b3os/hacker-news/get-item@1", "input": {"id": 8863}})print(result["output"])
json{ "method": "tools/call", "params": {"name": "hacker-news__get-item", "arguments": {"id": 8863}}}
Expose the pack as tools with --packs hacker-news on the local server or ?packs=hacker-news on the remote URL, and the agent calls hacker-news__get-item with the action's input. The tool needs no connection. Without exposing the pack, actions_call takes the same input with ref.
Output, labeled fixture: Get an item (response recorded 2026-10-26). From the bundle's fixtures/get-item.json, not a live call.
json{ "id": 8863, "type": "story", "by": "dhouston", "time": 1175714200, "title": "My YC app: Dropbox - Throw away your USB drive", "url": "http://www.getdropbox.com/u/2/screencast.html", "text": null, "score": 104, "descendants": 71, "parent": null, "kids": [9224, 8917, 8884, 8887], "dead": false, "deleted": false, "hn_url": "https://news.ycombinator.com/item?id=8863"}
When the service answers with an error, the call fails with upstream_error and pack_error.code is one of:
pack_error.code | Service status | Retryable | Message |
|---|---|---|---|
not_found | 200 | no | No Hacker News item with this id. |
get-user
Get a user. A Hacker News user's public profile: karma, account creation time, the about text (HTML) and how many items they submitted. Ids are case-sensitive.
Ref io.b3os/hacker-news/get-user@1.0.0 · effect read · no connection · MCP tool hacker-news__get-user
bashcurl -s https://beta-api.b3os.org/v1/actions/call \ -H "Authorization: Bearer $B3OS_API_KEY" \ -H "Content-Type: application/json" \ -d '{"ref": "io.b3os/hacker-news/get-user@1", "input": {"username": "pg"}}'
tsimport { B3OS } from "@b3os/sdk";const b3os = new B3OS();const result = await b3os.actions.call({ ref: "io.b3os/hacker-news/get-user@1", input: { username: "pg" } });console.log(result.output);
pythonfrom b3os import B3OSb3os = B3OS()result = b3os.actions.call({ "ref": "io.b3os/hacker-news/get-user@1", "input": {"username": "pg"},})print(result["output"])
json{ "method": "tools/call", "params": {"name": "hacker-news__get-user", "arguments": {"username": "pg"}}}
Expose the pack as tools with --packs hacker-news on the local server or ?packs=hacker-news on the remote URL, and the agent calls hacker-news__get-user with the action's input. The tool needs no connection. Without exposing the pack, actions_call takes the same input with ref.
Output, labeled fixture: Get a user (response recorded 2026-10-26). From the bundle's fixtures/get-user.json, not a live call.
json{ "id": "pg", "created": 1160418092, "karma": 157316, "about": "Bug fixer.", "submitted_count": 3}
When the service answers with an error, the call fails with upstream_error and pack_error.code is one of:
pack_error.code | Service status | Retryable | Message |
|---|---|---|---|
not_found | 200 | no | No Hacker News user with this name. |
Triggers
new-story
(trigger)
New story. Fires once for each new Hacker News item matching a query, checked every minute by default. The first check records what exists and emits nothing; later checks emit only items not seen before.
Ref io.b3os/hacker-news/new-story@1.0.0 · poll of search-recent, every 60 s by default (at least 30 s) · no connection
with key | Required | Description |
|---|---|---|
query | no | Words to match; empty matches every new item. Default "". |
type | no | Item type. Default "story". |
min_points | no | Minimum points. Default 0. |
In a routine:
yamltriggers: - type: action id: new_story uses: io.b3os/hacker-news/new-story@1
Event, labeled fixture: the first item of search-recent's fixture fixtures/search-recent.json (Search newest first (response recorded 2026-10-26)) through the trigger's event mapping. A routine reads it as trigger.data; its fields are id, title, url, hn_url, author, points, comments, created_at, created_at_i, text.
json{ "id": "50240115", "title": "Ask HN: Did crates.io stop processing new crate publishes?", "url": null, "hn_url": "https://news.ycombinator.com/item?id=50240115", "author": "davvid", "points": 1, "comments": 0, "created_at": "2026-10-26T07:03:21Z", "created_at_i": 1792998201, "text": "For example https://crates.io/crates/saphyr-parser/0.3.2/code was recently published (without any client-side errors) but crates.io says:<p><pre><code> The source code for this version is not available yet.\n\n Archives are built shortly after a version is published. This usually only takes a few seconds, so please try again in a couple of minutes.\n\n</code></pre>\nI've never seen this error before. The same can be seen by this just-published crate (12 minutes ago) says the same thing: https://crates.io/crates/skia-bindings/0.156.0/code<p>Does anyone know what's going on?"}