---
summary: "Enrichment release. Four new fields: `domain` on stories/search hits (hostname extracted from `url`), `highlights` on search hits (Algolia `_highlightResult` with `<em>…</em>` preserved), `isOp` on thread comments (author equals root item author), `omitted: { deleted, dead }` counters on threads. Closes #1, #2, #3, #4."
breaking: false
security: false
---

# 0.5.0 — 2026-05-11

Enrichment release — surfaces signal that was being dropped on the floor. Four feature additions across three tools, no breaking changes. Closes [#1](https://github.com/cyanheads/hn-mcp-server/issues/1), [#2](https://github.com/cyanheads/hn-mcp-server/issues/2), [#3](https://github.com/cyanheads/hn-mcp-server/issues/3), [#4](https://github.com/cyanheads/hn-mcp-server/issues/4).

## Added

- `hn_get_stories`, `hn_search_content`: new `domain` field on each result — bare hostname extracted from `url`, lowercased with leading `www.` stripped (e.g. `https://www.github.com/x` → `github.com`). Absent when `url` is missing or unparseable. Rendered as `(domain)` after the title in `format()` so the LLM and humans can pattern-match source at a glance instead of squinting at full URLs. Closes [#2](https://github.com/cyanheads/hn-mcp-server/issues/2).
- `hn_search_content`: new optional `highlights` object on each hit — projects Algolia's `_highlightResult` into `{ title?, text?, matchedWords[] }`. `title`/`text` preserve `<em>…</em>` markers around matched terms (other HTML stripped via the new `stripHtmlPreservingEm` helper); `text` falls back from `comment_text` to `story_text` to match the `text` mapping; `matchedWords` is the deduplicated union across all six searchable Algolia fields. Rendered as a `> match — …` footer alongside the raw title/body so structured consumers and `format()`-only clients both see what matched. Absent when `_highlightResult` is missing or no field produced a match. Closes [#1](https://github.com/cyanheads/hn-mcp-server/issues/1).
- `hn_get_thread`: new `isOp: boolean` field on each comment — true when the comment author equals the root item author (OP replying within their own thread), false when either author is missing. Rendered in `format()` as `**author (OP)**` in the comment header and as the literal `isOp:<bool>` token in the meta line. Closes [#3](https://github.com/cyanheads/hn-mcp-server/issues/3).
- `hn_get_thread`: new `omitted: { deleted, dead }` counters on the response — surfaces how many comments BFS traversal dropped because HN flagged them as moderated, so callers can tell a partial view apart from a `maxComments`-truncated one. Rendered as `(N deleted, M dead — omitted from this view)` footer when nonzero. Counts apply to the per-request BFS only; `filterLiveItems` (used by `hn_get_stories`, `hn_get_user`) continues to silently drop dead/deleted entries. Closes [#4](https://github.com/cyanheads/hn-mcp-server/issues/4).
- `extractDomain(url)` and `stripHtmlPreservingEm(html)` exported from `services/hn/hn-service.ts` — domain extraction reused by both `hn_get_stories` and `hn_search_content`; the EM-preserving stripper masks `<em>`/`</em>` with sentinel tokens before delegating to `stripHtml`, mirroring how code blocks are preserved.
- `AlgoliaHighlightValue` interface + `_highlightResult` field on `AlgoliaHit` in `services/hn/types.ts`.

## Changed

- `hn_get_thread`: format() author line now reads `**author (OP)**` for OP comments instead of plain `**author**`. Meta line gains `isOp:<bool>` token.
- `hn_get_thread`: comment meta line gains `isOp:<bool>` token (required by the linter's format-parity rule for boolean schema fields).

## Tests

- 147 passing (up from 111). New coverage: `extractDomain` and `stripHtmlPreservingEm` edge cases; domain derivation, omission, and rendering across `hn_get_stories` and `hn_search_content`; highlight mapping including comment-to-story fallback, dedup, and absence cases; thread `omitted` counting and `isOp` true/false/missing-author paths.
