@cyanheads/hn-mcp-server 0.5.13 → 0.5.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +18 -12
- package/Dockerfile +13 -7
- package/README.md +2 -1
- package/changelog/0.1.x/0.1.0.md +31 -0
- package/changelog/0.1.x/0.1.1.md +16 -0
- package/changelog/0.1.x/0.1.2.md +12 -0
- package/changelog/0.1.x/0.1.3.md +12 -0
- package/changelog/0.1.x/0.1.4.md +15 -0
- package/changelog/0.1.x/0.1.5.md +14 -0
- package/changelog/0.1.x/0.1.6.md +24 -0
- package/changelog/0.1.x/0.1.7.md +11 -0
- package/changelog/0.1.x/0.1.8.md +11 -0
- package/changelog/0.1.x/0.1.9.md +20 -0
- package/changelog/0.2.x/0.2.0.md +28 -0
- package/changelog/0.3.x/0.3.0.md +18 -0
- package/changelog/0.4.x/0.4.0.md +21 -0
- package/changelog/0.4.x/0.4.2.md +36 -0
- package/changelog/0.4.x/0.4.3.md +23 -0
- package/changelog/0.5.x/0.5.0.md +27 -0
- package/changelog/0.5.x/0.5.1.md +24 -0
- package/changelog/0.5.x/0.5.10.md +24 -0
- package/changelog/0.5.x/0.5.11.md +27 -0
- package/changelog/0.5.x/0.5.12.md +34 -0
- package/changelog/0.5.x/0.5.13.md +18 -0
- package/changelog/0.5.x/0.5.14.md +29 -0
- package/changelog/0.5.x/0.5.15.md +30 -0
- package/changelog/0.5.x/0.5.2.md +28 -0
- package/changelog/0.5.x/0.5.3.md +27 -0
- package/changelog/0.5.x/0.5.4.md +19 -0
- package/changelog/0.5.x/0.5.5.md +11 -0
- package/changelog/0.5.x/0.5.6.md +25 -0
- package/changelog/0.5.x/0.5.7.md +16 -0
- package/changelog/0.5.x/0.5.8.md +17 -0
- package/changelog/0.5.x/0.5.9.md +11 -0
- package/changelog/template.md +168 -0
- package/dist/services/hn/hn-service.d.ts +3 -1
- package/dist/services/hn/hn-service.d.ts.map +1 -1
- package/dist/services/hn/hn-service.js +36 -46
- package/dist/services/hn/hn-service.js.map +1 -1
- package/package.json +38 -24
- package/server.json +5 -5
package/CLAUDE.md
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Developer Protocol
|
|
2
2
|
|
|
3
3
|
**Server:** hn-mcp-server
|
|
4
|
-
**Version:** 0.5.
|
|
5
|
-
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core)
|
|
4
|
+
**Version:** 0.5.15
|
|
5
|
+
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.12.5`
|
|
6
|
+
**Engines:** Bun ≥1.3.0, Node ≥24.0.0
|
|
7
|
+
**MCP SDK:** `@modelcontextprotocol/server` 2.0.0
|
|
8
|
+
**Zod:** ^4.5.4
|
|
6
9
|
|
|
7
10
|
> **Read the framework docs first:** `node_modules/@cyanheads/mcp-ts-core/CLAUDE.md` contains the full API reference — builders, Context, error codes, exports, patterns. This file covers server-specific conventions only.
|
|
8
11
|
|
|
@@ -31,6 +34,8 @@ Tailor suggestions to what's actually missing or stale — don't recite the full
|
|
|
31
34
|
|
|
32
35
|
- **Logic throws, framework catches.** Tool/resource handlers are pure — throw on failure, no `try/catch`. Plain `Error` is fine; the framework catches, classifies, and formats. Use error factories (`notFound()`, `validationError()`, etc.) when the error code matters.
|
|
33
36
|
- **Use `ctx.log`** for request-scoped logging. No `console` calls.
|
|
37
|
+
- **Use `ctx.state`** for tenant-scoped storage. Never access persistence directly.
|
|
38
|
+
- **Need input the caller didn't supply?** `return ctx.requestInput(...)` and read `ctx.inputs` when the handler is re-entered. Never `await` for user input mid-handler.
|
|
34
39
|
- **Secrets in env vars only** — never hardcoded.
|
|
35
40
|
- **Close the loop on issues.** When implementing work tracked by a GitHub issue, comment on the issue with what landed and close it. Do both — a comment without a close leaves stale issues open; a close without a comment leaves no record of what shipped. The comment is for future readers — state the concrete changes, not the conversation that produced them.
|
|
36
41
|
|
|
@@ -64,9 +69,9 @@ export const getStories = tool('hn_get_stories', {
|
|
|
64
69
|
|
|
65
70
|
async handler(input, ctx) {
|
|
66
71
|
const hn = getHnService();
|
|
67
|
-
const feedIds = await hn.fetchFeed(input.feed);
|
|
72
|
+
const feedIds = await hn.fetchFeed(input.feed, ctx);
|
|
68
73
|
const sliced = feedIds.slice(input.offset, input.offset + input.count);
|
|
69
|
-
const items = filterLiveItems(await hn.fetchItems(sliced));
|
|
74
|
+
const items = filterLiveItems(await hn.fetchItems(sliced, ctx));
|
|
70
75
|
ctx.log.info('Fetched stories', { feed: input.feed, count: items.length });
|
|
71
76
|
return { stories: items.map(/* ... */), feed: input.feed, total: feedIds.length };
|
|
72
77
|
},
|
|
@@ -124,13 +129,13 @@ Handlers receive a unified `ctx` object. Key properties:
|
|
|
124
129
|
|
|
125
130
|
| Property | Description |
|
|
126
131
|
|:---------|:------------|
|
|
127
|
-
| `ctx.log` | Request-scoped logger — `.debug()`, `.info()`, `.notice()`, `.warning()`, `.error()`. Auto-correlates requestId, traceId, tenantId. |
|
|
132
|
+
| `ctx.log` | Request-scoped dual-sink logger — `.debug()`, `.info()`, `.notice()`, `.warning()`, `.error()`. Auto-correlates requestId, traceId, tenantId; eligible messages also reach the client through MCP logging notifications. |
|
|
128
133
|
| `ctx.state` | Tenant-scoped KV — `.get(key)`, `.set(key, value, { ttl? })`, `.delete(key)`, `.getMany(keys)`, `.list(prefix, { cursor, limit })`. Accepts any serializable value. |
|
|
129
|
-
| `ctx.
|
|
134
|
+
| `ctx.requestInput` | Suspend and ask the caller for more input — `return ctx.requestInput({ inputRequests: { key: inputRequired.elicit({ message, requestedSchema }) } })`. Never returns; the handler is re-entered with the answers. Always present. |
|
|
135
|
+
| `ctx.inputs` | Reader over a retried request's responses — `.accepted(key, schema)`, `.view(key)`, `.state()`, `.dropped`. Empty on the first round. |
|
|
130
136
|
| `ctx.enrich` | Success-path agent context (empty-result notices, query echo, pagination totals) — `ctx.enrich(...)` or `.notice()` / `.total()` / `.echo()` / `.truncated()`. Reaches `structuredContent` and `content[]`; lands only when the definition declares an `enrichment` block (no-op otherwise). |
|
|
131
137
|
| `ctx.content` | Non-text content blocks — `.image(data, mimeType)`, `.audio(data, mimeType)`, or `ctx.content(block)` for a raw block. Prepended to `content[]` after `format()`; never enters `structuredContent`. |
|
|
132
138
|
| `ctx.signal` | `AbortSignal` for cancellation. |
|
|
133
|
-
| `ctx.progress` | Task progress (present when `task: true`) — `.setTotal(n)`, `.increment()`, `.update(message)`. |
|
|
134
139
|
| `ctx.requestId` | Unique request ID. |
|
|
135
140
|
| `ctx.tenantId` | Tenant ID from JWT; `'default'` for stdio or HTTP with auth off. |
|
|
136
141
|
|
|
@@ -140,7 +145,7 @@ Handlers receive a unified `ctx` object. Key properties:
|
|
|
140
145
|
|
|
141
146
|
Handlers throw — the framework catches, classifies, and formats.
|
|
142
147
|
|
|
143
|
-
**Recommended: typed error contract.** Declare `errors: [{ reason, code, when, recovery, retryable? }]` on `tool()` / `resource()` to receive `ctx.fail(reason, …)` typed against the reason union. TypeScript catches typos at compile time, `data.reason` is auto-populated for observability, linter enforces conformance against the handler body. `recovery` is required descriptive metadata for the agent's next move (≥ 5 words, lint-validated); for the wire `data.recovery.hint` (mirrored into `content[]` text), pass explicitly at the throw site when dynamic context matters: `ctx.fail('reason', msg, { recovery: { hint: '...' } })`. Baseline codes (`InternalError`, `ServiceUnavailable`, `Timeout`, `ValidationError`, `SerializationError`) bubble freely and don't need declaring.
|
|
148
|
+
**Recommended: typed error contract.** Declare `errors: [{ reason, code, when, recovery, retryable? }]` on `tool()` / `resource()` to receive `ctx.fail(reason, …)` typed against the reason union. TypeScript catches typos at compile time, `data.reason` is auto-populated for observability, linter enforces conformance against the handler body. `recovery` is required descriptive metadata for the agent's next move (≥ 5 words, lint-validated); for the wire `data.recovery.hint` (mirrored into `content[]` text), pass explicitly at the throw site when dynamic context matters: `ctx.fail('reason', msg, { recovery: { hint: '...' } })`. Baseline codes (`InternalError`, `ServiceUnavailable`, `Timeout`, `ValidationError`, `SerializationError`, `RequestCancelled`) bubble freely and don't need declaring.
|
|
144
149
|
|
|
145
150
|
```ts
|
|
146
151
|
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
@@ -239,14 +244,14 @@ Available skills:
|
|
|
239
244
|
| `code-simplifier` | Post-session cleanup against `git diff` — modernize syntax, consolidate duplication, align with the codebase |
|
|
240
245
|
| `polish-docs-meta` | Finalize docs, README, metadata, and agent protocol for shipping |
|
|
241
246
|
| `git-wrapup` | Land working-tree changes as a versioned commit + annotated tag — version bump, changelog, verify, tag. Local only. |
|
|
242
|
-
| `release-and-publish` |
|
|
247
|
+
| `release-and-publish` | Push + npm + MCP Registry + GitHub Release + Docker. Picks up from `git-wrapup` |
|
|
243
248
|
| `maintenance` | Investigate changelogs, adopt upstream changes, sync skills to agent dirs |
|
|
244
249
|
| `orchestrations` | Chain task skills into a gated multi-phase pipeline — build-out, QA-fix, update-ship — when you can spawn sub-agents |
|
|
245
250
|
| `techniques` | Catalog of reusable response/data-shaping patterns (outline-on-overflow, etc.) |
|
|
246
251
|
| `api-auth` | Auth modes, scopes, JWT/OAuth |
|
|
247
252
|
| `api-canvas` | DataCanvas: register tabular data, run SQL, export, plus the `spillover()` helper for big result sets — Tier 3 opt-in |
|
|
248
253
|
| `api-config` | AppConfig, parseConfig, env vars |
|
|
249
|
-
| `api-context` | Context interface, logger, state,
|
|
254
|
+
| `api-context` | Context interface, RequestContext, logger, state, multi-round-trip input |
|
|
250
255
|
| `api-errors` | McpError, JsonRpcErrorCode, error patterns |
|
|
251
256
|
| `api-linter` | Definition linter rule catalog — invoked by `bun run lint:mcp` and `devcheck` |
|
|
252
257
|
| `api-mirror` | MirrorService: persistent self-refreshing local index (SQLite+FTS5) for bulk/slow upstream datasets |
|
|
@@ -285,6 +290,7 @@ When you complete a skill's checklist, check the boxes and add a completion time
|
|
|
285
290
|
| `bun run changelog:check` | Verify `CHANGELOG.md` is in sync (used by devcheck) |
|
|
286
291
|
| `bun run audit:refresh` | Delete `bun.lock`, reinstall, re-audit. Use when `devcheck` flags a transitive advisory — Bun's `update` is sticky on transitive resolutions, so the advisory may be a stale-lockfile false positive. If it survives the refresh, it's real. |
|
|
287
292
|
| `bun run test` | Run tests (Vitest — use `bun run test`, not `bun test`) |
|
|
293
|
+
| `bun run test:coverage` | Run the full Vitest suite with Istanbul coverage |
|
|
288
294
|
| `bun run start:stdio` | Production mode (stdio) |
|
|
289
295
|
| `bun run start:http` | Production mode (HTTP) |
|
|
290
296
|
|
|
@@ -317,7 +323,7 @@ security: false # optional — true ONLY for a source
|
|
|
317
323
|
...
|
|
318
324
|
```
|
|
319
325
|
|
|
320
|
-
`breaking: true` renders a `· ⚠️ Breaking` badge — use it when consumers must update code on upgrade (signature changes, removed APIs, config renames). `security: true` renders a `· 🛡️ Security` badge and pairs with a `## Security` body section — set it only for a security fix in this server's *own source code*, never for a routine dependency or transitive CVE bump (record those under `## Dependencies`).
|
|
326
|
+
`breaking: true` renders a `· ⚠️ Breaking` badge — use it when consumers must update code on upgrade (signature changes, removed APIs, config renames). `security: true` renders a `· 🛡️ Security` badge and pairs with a `## Security` body section — set it only for a security fix in this server's *own source code*, never for a routine dependency or transitive CVE bump (record those under `## Dependencies`). When both flags are set, the badges render `· ⚠️ Breaking · 🛡️ Security`.
|
|
321
327
|
|
|
322
328
|
`agent-notes` is an optional free-form field for maintenance agents processing the release downstream. Content there won't appear in the rendered CHANGELOG — it's consumed by agents running the `maintenance` skill. Use it for adoption instructions that don't fit the human-facing sections: new files to create, fields to populate, one-time migration steps. Omit entirely when there's nothing to say.
|
|
323
329
|
|
package/Dockerfile
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# This stage installs all dependencies (including dev), builds the TypeScript
|
|
5
5
|
# source code into JavaScript, and prepares the production assets.
|
|
6
6
|
# ==============================================================================
|
|
7
|
-
FROM oven/bun:1.
|
|
7
|
+
FROM --platform=$BUILDPLATFORM oven/bun:1.4.0 AS build
|
|
8
8
|
|
|
9
9
|
WORKDIR /usr/src/app
|
|
10
10
|
|
|
@@ -30,7 +30,7 @@ RUN bun run build
|
|
|
30
30
|
# application. It uses a slim base image and only includes production
|
|
31
31
|
# dependencies and build artifacts.
|
|
32
32
|
# ==============================================================================
|
|
33
|
-
FROM oven/bun:1.
|
|
33
|
+
FROM oven/bun:1.4.0-slim AS production
|
|
34
34
|
|
|
35
35
|
WORKDIR /usr/src/app
|
|
36
36
|
|
|
@@ -51,8 +51,11 @@ COPY package.json bun.lock ./
|
|
|
51
51
|
|
|
52
52
|
# Install only production dependencies, ignoring any lifecycle scripts (like 'prepare')
|
|
53
53
|
# that are not needed in the final production image.
|
|
54
|
+
# `--omit=peer` drops the framework's optional peer tiers; runtime imports must
|
|
55
|
+
# be declared by this server. The OTEL install below keeps the same flag so it
|
|
56
|
+
# does not pull those optional peers back into the image.
|
|
54
57
|
RUN --mount=type=cache,target=/root/.bun/install/cache \
|
|
55
|
-
bun install --production --frozen-lockfile --ignore-scripts
|
|
58
|
+
bun install --production --omit=peer --frozen-lockfile --ignore-scripts
|
|
56
59
|
|
|
57
60
|
# Conditionally install OpenTelemetry optional peer dependencies (Tier 3).
|
|
58
61
|
# These are not bundled by default to keep the base image lean. Enable at build time
|
|
@@ -60,7 +63,7 @@ RUN --mount=type=cache,target=/root/.bun/install/cache \
|
|
|
60
63
|
ARG OTEL_ENABLED=true
|
|
61
64
|
RUN --mount=type=cache,target=/root/.bun/install/cache \
|
|
62
65
|
if [ "$OTEL_ENABLED" = "true" ]; then \
|
|
63
|
-
bun add --omit=dev --ignore-scripts @hono/otel \
|
|
66
|
+
bun add --omit=dev --omit=peer --ignore-scripts @hono/otel \
|
|
64
67
|
@opentelemetry/instrumentation-http \
|
|
65
68
|
@opentelemetry/exporter-metrics-otlp-http \
|
|
66
69
|
@opentelemetry/exporter-trace-otlp-http \
|
|
@@ -81,6 +84,10 @@ COPY --from=build /usr/src/app/dist ./dist
|
|
|
81
84
|
# Create and set permissions for the log directory, assigning ownership to the 'bun' user.
|
|
82
85
|
RUN mkdir -p /var/log/hn-mcp-server && chown -R bun:bun /var/log/hn-mcp-server
|
|
83
86
|
|
|
87
|
+
# Writable data directories for framework-backed caches and mirrors.
|
|
88
|
+
RUN mkdir -p /usr/src/app/.cache /usr/src/app/.mirror \
|
|
89
|
+
&& chown -R bun:bun /usr/src/app/.cache /usr/src/app/.mirror
|
|
90
|
+
|
|
84
91
|
# Switch to the non-root user
|
|
85
92
|
USER bun
|
|
86
93
|
|
|
@@ -101,9 +108,8 @@ ENV MCP_FORCE_CONSOLE_LOGGING="true"
|
|
|
101
108
|
# Expose the port the server listens on
|
|
102
109
|
EXPOSE ${MCP_HTTP_PORT}
|
|
103
110
|
|
|
104
|
-
# Health check
|
|
105
|
-
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3
|
|
106
|
-
CMD bun -e "fetch('http://localhost:' + (process.env.MCP_HTTP_PORT || '3010') + '/healthz').then(r => process.exit(r.ok ? 0 : 1)).catch(() => process.exit(1))"
|
|
111
|
+
# Health check using a bun-native fetch (slim image ships no curl/wget)
|
|
112
|
+
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 CMD bun -e "fetch('http://localhost:'+(process.env.MCP_HTTP_PORT??'3010')+'/healthz').then((r)=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"
|
|
107
113
|
|
|
108
114
|
# The command to start the server
|
|
109
115
|
CMD ["bun", "run", "dist/index.js"]
|
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
<div align="center">
|
|
9
9
|
|
|
10
|
-
[](./CHANGELOG.md) [](./LICENSE) [](https://github.com/users/cyanheads/packages/container/package/hn-mcp-server) [](https://modelcontextprotocol.io/) [](https://www.npmjs.com/package/@cyanheads/hn-mcp-server) [](https://www.typescriptlang.org/) [](https://bun.sh/)
|
|
11
11
|
|
|
12
12
|
</div>
|
|
13
13
|
|
|
@@ -191,6 +191,7 @@ All configuration is via environment variables. No API keys required — HN APIs
|
|
|
191
191
|
| `MCP_TRANSPORT_TYPE` | Transport: `stdio` or `http`. | `stdio` |
|
|
192
192
|
| `MCP_HTTP_PORT` | HTTP server port. | `3010` |
|
|
193
193
|
| `MCP_HTTP_HOST` | HTTP server host. | `localhost` |
|
|
194
|
+
| `MCP_SESSION_MODE` | HTTP session handling: `auto`, `stateful`, or `stateless`. `auto` resolves to `stateful`. The published Docker image and `.env.example` pin `stateless`. | `auto` |
|
|
194
195
|
| `MCP_LOG_LEVEL` | Log level: `debug`, `info`, `notice`, `warning`, `error`. | `info` |
|
|
195
196
|
| `LOGS_DIR` | Directory for log files (Node.js only). | `<project-root>/logs` |
|
|
196
197
|
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Initial release. Four read-only tools (`hn_get_stories`, `hn_get_thread`, `hn_get_user`, `hn_search_content`) over HN Firebase + Algolia. Concurrency-limited batch fetching, HTML stripping with code-block/link preservation, stdio + streamable-http transports."
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.1.0 — 2026-03-21
|
|
8
|
+
|
|
9
|
+
Initial release.
|
|
10
|
+
|
|
11
|
+
## Added
|
|
12
|
+
|
|
13
|
+
- **Tools:** `get_stories`, `get_thread`, `get_user`, `search_hn` — 4 read-only tools covering HN feeds, threaded discussions, user profiles, and full-text search
|
|
14
|
+
- **Service layer:** HN Firebase API client with concurrency-limited batch fetching, Algolia search client with filtering and pagination
|
|
15
|
+
- **HTML processing:** Entity decoding, tag stripping with code block and link preservation
|
|
16
|
+
- **Transports:** stdio and streamable-http via `@cyanheads/mcp-ts-core`
|
|
17
|
+
- **Configuration:** `HN_CONCURRENCY_LIMIT` env var for tuning batch fetch parallelism
|
|
18
|
+
- **Tests:** Comprehensive test suite covering all tools, service layer, and server config
|
|
19
|
+
- **Docs:** README with full tool documentation, design document, HN API reference, project structure tree
|
|
20
|
+
- **Infra:** Dockerfile, biome config, vitest config, devcheck config, server.json metadata, LICENSE (Apache-2.0), bunfig.toml
|
|
21
|
+
|
|
22
|
+
## Fixed
|
|
23
|
+
|
|
24
|
+
- `search_hn` totalPages calculation now uses `Math.ceil(nbHits / count)` instead of Algolia's `nbPages` (which reflects Algolia's own page size, not the requested count)
|
|
25
|
+
|
|
26
|
+
## Changed
|
|
27
|
+
|
|
28
|
+
- Updated `server.json` name to reverse-DNS format (`io.github.cyanheads/hn-mcp-server`), added `HN_CONCURRENCY_LIMIT` env var, set `runtimeHint` to `bun`
|
|
29
|
+
- Expanded `package.json` with `mcpName`, `homepage`, `bugs`, `author`, `packageManager`, and HN-specific keywords
|
|
30
|
+
- Added OCI image description and source labels to Dockerfile
|
|
31
|
+
- Customized `CLAUDE.md` agent protocol with HN-specific patterns, examples, and structure
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Renamed package to scoped `@cyanheads/hn-mcp-server`. Conditional OpenTelemetry install via `OTEL_ENABLED` Docker build arg. Framework `^0.1.22 → ^0.1.23`."
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.1.1 — 2026-03-21
|
|
8
|
+
|
|
9
|
+
## Changed
|
|
10
|
+
|
|
11
|
+
- Renamed package from `hn-mcp-server` to `@cyanheads/hn-mcp-server` (scoped npm package)
|
|
12
|
+
- Bumped `@cyanheads/mcp-ts-core` from `^0.1.22` to `^0.1.23`
|
|
13
|
+
- Added `@hono/otel` dependency for OpenTelemetry integration
|
|
14
|
+
- Dockerfile now conditionally installs OpenTelemetry peer dependencies via `OTEL_ENABLED` build arg (defaults to true)
|
|
15
|
+
- Updated `server.json` npm identifiers to scoped package name
|
|
16
|
+
- Updated README install commands to use scoped package name
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Framework patch `^0.1.23 → ^0.1.24`. Publishing instructions added to CLAUDE.md."
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.1.2 — 2026-03-21
|
|
8
|
+
|
|
9
|
+
## Changed
|
|
10
|
+
|
|
11
|
+
- Bumped `@cyanheads/mcp-ts-core` from `^0.1.23` to `^0.1.24`
|
|
12
|
+
- Added publishing instructions to `CLAUDE.md` agent protocol
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Framework patch `^0.1.23 → ^0.1.25`."
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.1.3 — 2026-03-21
|
|
8
|
+
|
|
9
|
+
## Changed
|
|
10
|
+
|
|
11
|
+
- Bumped `@cyanheads/mcp-ts-core` from `^0.1.23` to `^0.1.25`
|
|
12
|
+
- Added publishing instructions to `CLAUDE.md` agent protocol
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "TypeScript major `^5.9.3 → ^6.0.2`. Framework `^0.1.25 → ^0.1.28`. Vitest patch. `remotes` entry on `server.json` with public streamable-http URL. `tsconfig.json` simplified (relative path alias)."
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.1.4 — 2026-03-23
|
|
8
|
+
|
|
9
|
+
## Changed
|
|
10
|
+
|
|
11
|
+
- Bumped `@cyanheads/mcp-ts-core` from `^0.1.25` to `^0.1.28`
|
|
12
|
+
- Bumped `typescript` from `^5.9.3` to `^6.0.2`
|
|
13
|
+
- Bumped `vitest` from `^4.1.0` to `^4.1.1`
|
|
14
|
+
- Added `remotes` entry to `server.json` with public streamable-http URL
|
|
15
|
+
- Simplified `tsconfig.json`: removed `baseUrl`, updated path alias to relative form
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Tool rename pass: all four tools gain `hn_` namespace prefix (`get_stories` → `hn_get_stories`, `get_thread` → `hn_get_thread`, `get_user` → `hn_get_user`, `search_hn` → `hn_search_content`). Breaking for any caller using the unprefixed names."
|
|
3
|
+
breaking: true
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.1.5 — 2026-03-23
|
|
8
|
+
|
|
9
|
+
## Changed
|
|
10
|
+
|
|
11
|
+
- Renamed all tools with `hn_` prefix for namespacing: `get_stories` → `hn_get_stories`, `get_thread` → `hn_get_thread`, `get_user` → `hn_get_user`, `search_hn` → `hn_search_content`
|
|
12
|
+
- Renamed `search-hn.tool.ts` → `search-content.tool.ts` (and corresponding test) to match new tool name
|
|
13
|
+
- Updated cross-reference descriptions in tool schemas to use new prefixed names
|
|
14
|
+
- Updated README, CLAUDE.md, and test suites with new tool names
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Framework `^0.1.28 → ^0.2.4`. `format()` output overhauled across all tools (markdown headers, IDs, dates, actionable hints). Security overrides for `path-to-regexp`, `picomatch`, `brace-expansion`. New `report-issue-framework` / `report-issue-local` skills."
|
|
3
|
+
breaking: false
|
|
4
|
+
security: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.1.6 — 2026-03-28
|
|
8
|
+
|
|
9
|
+
## Changed
|
|
10
|
+
|
|
11
|
+
- Bumped `@cyanheads/mcp-ts-core` from `^0.1.28` to `^0.2.4`
|
|
12
|
+
- Bumped `@biomejs/biome` from `^2.4.8` to `^2.4.9`
|
|
13
|
+
- Bumped `vitest` from `^4.1.1` to `^4.1.2`
|
|
14
|
+
- Added `overrides` for `path-to-regexp`, `picomatch`, and `brace-expansion` (security patches)
|
|
15
|
+
- Improved `format()` output across all 4 tools: markdown headers, item IDs, dates, full text rendering, and actionable hints
|
|
16
|
+
- Updated test assertions to match new format output
|
|
17
|
+
|
|
18
|
+
## Added
|
|
19
|
+
|
|
20
|
+
- `report-issue-framework` skill for filing bugs against `@cyanheads/mcp-ts-core`
|
|
21
|
+
- `report-issue-local` skill for filing bugs against this server
|
|
22
|
+
- `LOGS_DIR` env var documented in README
|
|
23
|
+
- GitHub repo metadata sync step in `polish-docs-meta` skill
|
|
24
|
+
- Description propagation rule (package.json → README → server.json → Dockerfile)
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Framework `^0.2.7 → ^0.2.10`. Biome patch. Skill refreshes — `add-tool` v1.1 (tool response design), `add-resource` v1.1 (tool coverage guidance), `design-mcp-server` v2.1 (live API probing, batch input design, resilience planning)."
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.1.9 — 2026-03-30
|
|
8
|
+
|
|
9
|
+
## Changed
|
|
10
|
+
|
|
11
|
+
- Bumped `@cyanheads/mcp-ts-core` from `^0.2.7` to `^0.2.10`
|
|
12
|
+
- Bumped `@biomejs/biome` from `^2.4.9` to `^2.4.10`
|
|
13
|
+
- Updated author field and added funding metadata in `package.json`
|
|
14
|
+
- Updated `add-tool` skill (v1.1): expanded tool response design guidance — partial success, batch input, format function content-completeness, error classification
|
|
15
|
+
- Updated `add-resource` skill (v1.1): added tool coverage guidance for resource definitions
|
|
16
|
+
- Updated `design-mcp-server` skill (v2.1): live API probing, tool-first design philosophy, batch input design, error design patterns, resilience planning, naming conventions
|
|
17
|
+
|
|
18
|
+
## Fixed
|
|
19
|
+
|
|
20
|
+
- Formatting fix in `get-thread.tool.test.ts` assertion
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Upstream resilience. `withRetry` + `fetchWithTimeout` wrap HN Firebase + Algolia fetches with 10s per-request timeout, HTML-error-body detection (for rate-limited 200 OK responses), and `ctx.signal` cancellation. `hn_get_stories` schema fields made optional to preserve upstream sparsity. Framework `^0.2.10 → ^0.4.1`."
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.2.0 — 2026-04-19
|
|
8
|
+
|
|
9
|
+
## Added
|
|
10
|
+
|
|
11
|
+
- Upstream resilience for HN Firebase and Algolia calls: `withRetry` + `fetchWithTimeout` wrap the full fetch-and-parse pipeline in `HnService`, with a 10-second per-request timeout, HTML-error-body detection (for rate-limited responses served as 200 OK), and `ctx.signal` wired through for cancellation.
|
|
12
|
+
- Sparse-upstream test fixtures for `hn_get_stories` covering omitted `score`/`by`/`time`/`title` fields and verifying `format()` does not fabricate meta.
|
|
13
|
+
- `add-app-tool` skill (v1.2) for scaffolding MCP App tool + UI resource pairs.
|
|
14
|
+
|
|
15
|
+
## Changed
|
|
16
|
+
|
|
17
|
+
- Bumped `@cyanheads/mcp-ts-core` from `^0.2.10` to `^0.4.1`.
|
|
18
|
+
- Bumped `@biomejs/biome` (2.4.10 → 2.4.12), `@types/node` (25.5.0 → 25.6.0), `typescript` (6.0.2 → 6.0.3), `vitest` (4.1.2 → 4.1.4).
|
|
19
|
+
- Dropped the `overrides` block (`path-to-regexp`, `picomatch`, `brace-expansion`) — fresh resolution picks up clean transitive versions and `bun audit` now reports zero vulnerabilities.
|
|
20
|
+
- `HnService` methods (`fetchItem`, `fetchUser`, `fetchFeed`, `fetchItems`, `search`) now accept `ctx: Context` for correlated logs and cancellation; added a local `toRequestContext()` adapter to reconcile `exactOptionalPropertyTypes` differences between `Context` and `RequestContext`.
|
|
21
|
+
- `hn_get_stories` output schema: `title`, `score`, `by`, and `time` are now optional. The handler uses conditional spreads so upstream absence is preserved instead of being fabricated into `''`, `0`, or epoch zero. `format()` falls back to `[type]` when the title is unknown and omits meta segments that would otherwise render as blank.
|
|
22
|
+
- `hn_get_thread` and `hn_get_user` now throw `notFound()` for missing items/users instead of plain `Error`, giving the LLM a classified error code.
|
|
23
|
+
- Algolia HTTP error paths now surface as `ServiceUnavailable` via `fetchWithTimeout` + retry instead of raw `Error`.
|
|
24
|
+
- Synced project skills from `mcp-ts-core@0.4.1`: updated `add-prompt`, `add-resource`, `add-service`, `add-test`, `add-tool`, `api-testing`, `api-workers`, `design-mcp-server`, `devcheck`, `field-test`, `maintenance`, `migrate-mcp-ts-template`, `polish-docs-meta`, `setup`.
|
|
25
|
+
|
|
26
|
+
## Fixed
|
|
27
|
+
|
|
28
|
+
- Per-item failures inside batch `fetchItems` calls are now tolerated (logged and nulled) rather than bubbling up and failing the whole feed after retries exhaust.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Framework `^0.4.1 → ^0.5.3` adopts the `format-parity` lint rule. `format()` output expanded across all four tools: meta lines lead with `id:N`, dual ISO + Unix timestamps, comment depth/parent annotations, indent capped at 10 levels."
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.3.0 — 2026-04-20
|
|
8
|
+
|
|
9
|
+
## Changed
|
|
10
|
+
|
|
11
|
+
- Bumped `@cyanheads/mcp-ts-core` from `^0.4.1` to `^0.5.3`. The 0.5.x release adds a `format-parity` lint rule that verifies every field in a tool's `output` schema is rendered by its `format()` function — catching silent divergence between `structuredContent` (forwarded by clients like Claude Code) and `content[]` (forwarded by clients like Claude Desktop).
|
|
12
|
+
- `hn_get_stories` `format()`: meta line now leads with `id:N | type | …` and renders `time` as both ISO date and raw Unix timestamp (`2026-04-20 (t:1776717572)`); header includes raw `offset:N`.
|
|
13
|
+
- `hn_get_thread` `format()`: comment lines now include `depth:N | parent:N` annotations; visual indent is capped at 10 levels so a synthetic deep depth doesn't OOM `String.repeat`; root meta includes `type:N`; comment timestamps render with both formatted date and raw value; summary is always rendered (previously suppressed when fully loaded).
|
|
14
|
+
- `hn_get_user` `format()`: `created` and submission `time` now render with both formatted date and raw Unix timestamp.
|
|
15
|
+
- `hn_search_content` `format()`: header includes raw `p:N`; `createdAt` now renders the full ISO string (was truncated to date); comment results carry the parent story id in the heading; story results suppress the redundant self-referential parent ref.
|
|
16
|
+
- Dropped redundant `async` modifier on `HnService.fetchItem`/`fetchUser`/`fetchFeed` — they delegate directly to `withRetry()` and gain nothing from the wrapper.
|
|
17
|
+
- Synced project skills from `mcp-ts-core@0.5.3`: updated `add-tool` (1.4 → 1.6), `api-config` (1.1 → 1.2), `design-mcp-server` (2.3 → 2.4), `field-test` (1.1 → 1.2), `maintenance` (1.2 → 1.3), `polish-docs-meta` (1.3 → 1.4), `setup` (1.2 → 1.3).
|
|
18
|
+
- Bumped MCP SDK badge in `README.md` to `^1.29.0` and TypeScript badge to `^6.0.3`.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Framework `^0.5.3 → ^0.7.0` (20 releases). `.describe()` now required recursively on array-element schemas — added to `stories[]`, `comments[]`, `submissions[]`, `hits[]`. New skills `api-linter`, `release-and-publish`, `security-pass`. `.github/ISSUE_TEMPLATE/` scaffolded."
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.4.0 — 2026-04-24
|
|
8
|
+
|
|
9
|
+
## Changed
|
|
10
|
+
|
|
11
|
+
- Bumped `@cyanheads/mcp-ts-core` from `^0.5.3` to `^0.7.0`. Spans 20 releases with substantial additions: landing page at `/` plus SEP-1649 Server Card at `/.well-known/mcp.json`, `MCP_PUBLIC_URL` override for TLS-terminating proxies, directory-based changelog convention, recursive `describe-on-fields` linter, new `security-pass` / `release-and-publish` / `api-linter` skills, a `Skills Sync` devcheck step, and flattened `ZodError` message shape. No runtime breaking changes for this server.
|
|
12
|
+
- `hn_get_stories`, `hn_get_thread`, `hn_get_user`, `hn_search_content`: added `.describe()` on each array-element object schema (`stories[]`, `comments[]`, `submissions[]`, `hits[]`) to satisfy the new recursive `describe-on-fields` rule introduced in `mcp-ts-core@0.6.16`.
|
|
13
|
+
- `hn_get_stories` handler: hoisted `normalizeUrl(item.url)` to a local `const` so it's called once per story instead of twice, and dropped the redundant `as string` cast. The conditional-spread "omit absent properties" contract is preserved.
|
|
14
|
+
- Bumped `@biomejs/biome` (2.4.12 → 2.4.13) and `vitest` (4.1.4 → 4.1.5).
|
|
15
|
+
|
|
16
|
+
## Added
|
|
17
|
+
|
|
18
|
+
- `.github/ISSUE_TEMPLATE/` — bug report, feature request, and config templates scaffolded from the framework, aligned with `mcp-ts-core@0.7.0`'s secondary-label scheme.
|
|
19
|
+
- Framework scripts synced from `mcp-ts-core@0.7.0`: `scripts/build-changelog.ts`, `scripts/check-docs-sync.ts`, `scripts/check-skills-sync.ts`. `devcheck`, `lint-mcp`, and `tree` scripts also refreshed.
|
|
20
|
+
- Skills synced from `mcp-ts-core@0.7.0`: added `api-linter` (v1.1), `release-and-publish` (v2.1), `security-pass` (v1.1); updated `add-app-tool`, `add-prompt`, `add-resource`, `add-service`, `add-tool`, `api-context`, `api-services`, `api-utils`, `design-mcp-server`, `field-test`, `maintenance`, `polish-docs-meta`, `report-issue-framework`, `report-issue-local`, `setup`. Propagated to `.claude/skills/`.
|
|
21
|
+
- `CLAUDE.md`: added `security-pass` step to the "What's Next?" sequence (slot 8); added `security-pass`, `release-and-publish`, and `api-linter` rows to the skills table; pointed the Publishing section at the `release-and-publish` skill.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Bundles two releases. (1) `hn_search_content` `dateRange` rejects unparseable dates via Zod `.refine()`. (2) Framework `^0.7.0 → ^0.8.17` brings the typed-error-contract API; adopted contracts on `hn_get_thread` (`item_not_found`) and `hn_get_user` (`user_not_found`); search empty-result message names applied filters."
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.4.2 — 2026-05-05
|
|
8
|
+
|
|
9
|
+
## Changed
|
|
10
|
+
|
|
11
|
+
- `hn_search_content`: `dateRange.start` and `dateRange.end` now reject unparseable date strings at the input boundary via a Zod `.refine()` check, instead of silently producing `NaN` Algolia numeric filters when downstream `new Date(…).getTime()` fails. New test covers the rejection path.
|
|
12
|
+
- `hn_search_content`: clarified `storyId` description to call out that it equals `id` for story hits and points to the parent story for comment hits. Tightened the empty-results `message` description to read more naturally.
|
|
13
|
+
- `hn_get_thread`: typo fix and clarity in two field descriptions — `commentId` → `comment's itemId` in the `depth` guidance, and `comments[]` description now spells out the BFS-by-rank order instead of leaning on the abbreviation.
|
|
14
|
+
- `CLAUDE.md`: synced agent protocol header from `0.4.0` to current.
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
## Changed
|
|
19
|
+
|
|
20
|
+
- Bumped `@cyanheads/mcp-ts-core` from `^0.7.0` to `^0.8.17`. Brings the typed-error-contract API (`tool({ errors: […] })` + `ctx.fail(reason, …)` + `ctx.recoveryFor(reason)`), recovery-hint mirroring into `content[]`, the `Framework Antipatterns` devcheck step, two new project skills (`api-canvas`, `tool-defs-analysis`), and refinements to several existing skills. No runtime breaks.
|
|
21
|
+
- `hn_get_thread`: declared `errors: [{ reason: 'item_not_found', code: NotFound, when, recovery }]`. Replaced `notFound()` throw with `ctx.fail('item_not_found', …, { itemId, ...ctx.recoveryFor('item_not_found') })` so the recovery hint flows onto the wire and is mirrored into rendered text for `format()`-only clients.
|
|
22
|
+
- `hn_get_user`: same treatment for `user_not_found` — typed contract, `ctx.fail`, recovery spread.
|
|
23
|
+
- `hn_search_content`: empty-result responses now include an optional `message` field that names which filters were applied (`tags`, `author`, `minPoints`, `dateRange`) so the agent knows what to relax. Rendered as a recovery sentence when no hits, and as a `>` blockquote footer on non-empty pages whenever a message was generated. Output schema gains the `message?` field.
|
|
24
|
+
- `HnService.parseJsonBody`: HTML-error-body throw (rate-limited upstream returning 200 OK with HTML) now carries `data: { upstream, reason: 'upstream_html', recovery: { hint } }`, so service-layer failures expose the same shape `format()`-only clients get from the typed contract.
|
|
25
|
+
- Tool descriptions and field `.describe()` strings tightened across all four tools — sharper guidance on `count`/`offset`/`depth`/`maxComments`, and the `type` field now lists the actual HN item types.
|
|
26
|
+
- Bumped `@biomejs/biome` (2.4.13 → 2.4.14) and `tsc-alias` (1.8.16 → 1.8.17).
|
|
27
|
+
|
|
28
|
+
## Added
|
|
29
|
+
|
|
30
|
+
- `scripts/check-framework-antipatterns.ts` and a matching `Framework Antipatterns` step in `devcheck` — flags SDK-coupling shortcuts that bypass framework primitives.
|
|
31
|
+
- `scripts/split-changelog.ts` — framework helper for splitting `CHANGELOG.md` into per-version files.
|
|
32
|
+
- Project skills synced from `mcp-ts-core@0.8.17`: added `api-canvas` (DataCanvas + spillover), `tool-defs-analysis` (read-only audit of MCP definition language); refreshed `add-service`, `add-tool`, `api-config`, `api-context`, `api-errors`, `api-linter`, `api-workers`, `design-mcp-server`, `field-test`, `maintenance`, `release-and-publish`, `report-issue-framework`, `report-issue-local`, `security-pass`, `setup`. Propagated to `.claude/skills/`.
|
|
33
|
+
|
|
34
|
+
## Removed
|
|
35
|
+
|
|
36
|
+
- `dev:stdio` and `dev:http` package scripts — `bun --watch src/index.ts` is invoked directly.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Maintenance. Framework `^0.8.17 → ^0.8.20` (bundles `hono` security patches GHSA-p77w-8qqv-26rm / GHSA-qp7p-654g-cw7p / GHSA-hm8q-7f3q-5f36). Engine bumps `bun >=1.3` / `node >=24`, Dockerfile base `oven/bun:1.3`. `@hono/otel` + `pino-pretty` moved to devDependencies. New `api-telemetry` skill."
|
|
3
|
+
breaking: false
|
|
4
|
+
security: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.4.3 — 2026-05-11
|
|
8
|
+
|
|
9
|
+
Maintenance release — framework bump, runtime engine bump, dependency reorg. No application code changes.
|
|
10
|
+
|
|
11
|
+
## Changed
|
|
12
|
+
|
|
13
|
+
- Bumped `@cyanheads/mcp-ts-core` from `^0.8.17` to `^0.8.20`. Brings: `ctx.auth.token` reaches handlers (0.8.18, [cyanheads/mcp-ts-core#121](https://github.com/cyanheads/mcp-ts-core/issues/121)); telemetry visualization docs + `api-telemetry` skill (0.8.19, [cyanheads/mcp-ts-core#125](https://github.com/cyanheads/mcp-ts-core/issues/125)); `mcp_tool_scopes` claim union and `MCP_AUTH_DISABLE_SCOPE_CHECKS` bypass for OIDC providers that can't inject scopes into `scope` (0.8.20, [cyanheads/mcp-ts-core#128](https://github.com/cyanheads/mcp-ts-core/issues/128)). Bundles `hono` security patches (GHSA-p77w-8qqv-26rm, GHSA-qp7p-654g-cw7p, GHSA-hm8q-7f3q-5f36). No surface this server exposes is affected, but the floor is now pinned to a patched `hono` peer. No runtime breaks for this server.
|
|
14
|
+
- **Engines:** `bun >=1.2.0 → >=1.3.0`, `node >=22.0.0 → >=24.0.0`. Mirrors the framework's new minimums.
|
|
15
|
+
- **Dockerfile:** base image `oven/bun:1 → oven/bun:1.3` (build + runtime stages).
|
|
16
|
+
- **Dependency reorg:** `@hono/otel` and `pino-pretty` moved from `dependencies` to `devDependencies`. Both are optional framework peers — this server doesn't emit OTel HTTP middleware traces and doesn't ship pretty-printed logs in production. Removing them from the runtime dependency set drops install size without affecting behavior.
|
|
17
|
+
- **Dependency refresh:** `@cyanheads/mcp-ts-core ^0.8.17 → ^0.8.20`, `@biomejs/biome ^2.4.14 → ^2.4.15`, `@types/node ^25.6.0 → ^25.6.2`, `@hono/otel ^1.1.1 → ^1.1.2` (now dev-only).
|
|
18
|
+
|
|
19
|
+
## Added
|
|
20
|
+
|
|
21
|
+
- Project skill synced from `mcp-ts-core@0.8.19`: `api-telemetry` — catalog of every span, metric, attribute, completion-log field, env var, and runtime caveat the framework emits. Cross-linked from `api-utils` (now scoped to the helper API only) and from the `CLAUDE.md` skill index.
|
|
22
|
+
- `scripts/build-changelog.ts` resynced from upstream: adds `security: boolean` frontmatter flag that renders a `🛡️ Security` badge in the rollup, alongside the existing `breaking` flag.
|
|
23
|
+
- Refreshed skills synced from upstream (no version regressions): `api-auth` 1.0 → 1.1 (OIDC operator setup, claim-union table, bypass flag), `api-config` 1.3 → 1.4 (new `MCP_AUTH_DISABLE_SCOPE_CHECKS` env row), `api-utils` 2.1 → 2.2 (telemetry section points at the new `api-telemetry` skill), `maintenance` 2.0 → 2.1 (Phase C now resyncs pristine reference files like `changelog/template.md`), `report-issue-framework` 1.5 → 1.6 and `report-issue-local` 1.4 → 1.5 (terser issue-writing guidance, `bun 1.3.x` examples), `security-pass` 1.3 → 1.4 (bypass-in-production check), `setup` 1.6 → 1.7 (`bunx` over `npx`, substituted-name verification, `release-and-publish` in progression), `tool-defs-analysis` 1.0 → 1.1 (env vars no longer flagged as recovery-hint smell). All propagated to `.claude/skills/`.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
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."
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.5.0 — 2026-05-11
|
|
8
|
+
|
|
9
|
+
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).
|
|
10
|
+
|
|
11
|
+
## Added
|
|
12
|
+
|
|
13
|
+
- `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).
|
|
14
|
+
- `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).
|
|
15
|
+
- `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).
|
|
16
|
+
- `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).
|
|
17
|
+
- `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.
|
|
18
|
+
- `AlgoliaHighlightValue` interface + `_highlightResult` field on `AlgoliaHit` in `services/hn/types.ts`.
|
|
19
|
+
|
|
20
|
+
## Changed
|
|
21
|
+
|
|
22
|
+
- `hn_get_thread`: format() author line now reads `**author (OP)**` for OP comments instead of plain `**author**`. Meta line gains `isOp:<bool>` token.
|
|
23
|
+
- `hn_get_thread`: comment meta line gains `isOp:<bool>` token (required by the linter's format-parity rule for boolean schema fields).
|
|
24
|
+
|
|
25
|
+
## Tests
|
|
26
|
+
|
|
27
|
+
- 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.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "`hn_get_thread` schema patch: `comments[].isOp` and `omitted` are now absence-by-default. `isOp` changed `z.boolean()` → `z.literal(true).optional()`; `omitted` made optional. Wire payload shrinks on the common case (no OP reply, no moderation truncation); `format()` output unchanged."
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.5.1 — 2026-05-11
|
|
8
|
+
|
|
9
|
+
Patch to `hn_get_thread` — two response fields that were always present but rarely informative (`comments[].isOp` and `omitted`) are now absence-by-default and only emitted when they carry signal. The 0.5.0 shape required `isOp: boolean` on every comment and `omitted: { deleted, dead }` on every response, which on the common case (no OP reply, no moderation truncation) emitted `false` and `{ 0, 0 }` for zero information. Aligns these two fields with the rest of the schema — `title`, `url`, `score`, `text`, etc. are all absent-when-missing rather than `null`-filled. Wire payload shrinks across both fields; `format()` output is unchanged on the common case and identical on the signal case.
|
|
10
|
+
|
|
11
|
+
## Changed
|
|
12
|
+
|
|
13
|
+
- `hn_get_thread`: `comments[].isOp` schema changed from `z.boolean()` to `z.literal(true).optional()`. Field is omitted from `structuredContent` when the comment is not an OP reply (including when either author is missing).
|
|
14
|
+
- `hn_get_thread`: `omitted` schema changed from required to `.optional()`. Field is omitted from `structuredContent` when no comments were dropped during BFS traversal. Present only when `deleted > 0 || dead > 0`.
|
|
15
|
+
- `hn_get_thread`: `format()` meta line emits the `| isOp:true` token only when the field is present and true. The `**author (OP)**` author suffix continues to render unchanged when `isOp: true`. `format()` already gated the omitted-summary footer on `> 0` in 0.5.0, so rendered output is unchanged.
|
|
16
|
+
|
|
17
|
+
## Consumer contract
|
|
18
|
+
|
|
19
|
+
- Treat missing `comments[i].isOp` as "not OP" rather than "unknown". Truthy checks (`if (c.isOp)`, `c.isOp === true`) work identically to 0.5.0; only `c.isOp === false` flips behavior (and was always the wrong way to check).
|
|
20
|
+
- Treat missing `omitted` as `{ deleted: 0, dead: 0 }`. Same pattern.
|
|
21
|
+
|
|
22
|
+
## Tests
|
|
23
|
+
|
|
24
|
+
- 147 passing. Updated assertions in three handler tests (`isOp: false` → `not.toHaveProperty('isOp')`), removed `isOp: false` from four format-test fixtures, strengthened the OP format test to verify `| isOp:true` appears for the OP comment and `isOp:false` never appears in rendered output. Updated two handler tests for `omitted` absence (`expect(result).not.toHaveProperty('omitted')`) and removed the now-redundant `omitted: { deleted: 0, dead: 0 }` lines from six format-test fixtures.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "@cyanheads/mcp-ts-core ^0.9.21 → ^0.10.6 — truncation enrichment signals on every tool, explicit server identity, hardened MCPB bundle packaging"
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.5.10 — 2026-06-12
|
|
8
|
+
|
|
9
|
+
## Added
|
|
10
|
+
|
|
11
|
+
- **Truncation enrichment** — `hn_get_stories`, `hn_get_thread`, `hn_get_user`, and `hn_search_content` emit `truncated`/`shown`/`cap` enrichment fields via `ctx.enrich.truncated()` when a result is capped by its count/`maxComments`/`submissionCount` parameter.
|
|
12
|
+
- **`HEALTHCHECK`** — the Docker image now probes `/healthz` (30s interval) so orchestrators see container health.
|
|
13
|
+
|
|
14
|
+
## Changed
|
|
15
|
+
|
|
16
|
+
- **`@cyanheads/mcp-ts-core` ^0.9.21 → ^0.10.6** — framework adoption.
|
|
17
|
+
- **Server identity** — `createApp()` now sets `name`/`title` to `hn-mcp-server` explicitly; `.codex-plugin` `displayName` drops the npm scope.
|
|
18
|
+
- **`bundle`** — runs `scripts/clean-mcpb.ts` after `mcpb pack`: official dev-dependency prune plus an exact-name strip of dependency-shipped agent docs (`skills/`, `.claude/`, `.agents/`, `SKILL.md`) nested under `node_modules/` that root-anchored `.mcpbignore` patterns cannot reach.
|
|
19
|
+
- **`lint:packaging`** — adds bundle-content guards (root dev dirs excluded, `.mcpbignore` patterns anchored, critical runtime paths preserved, built `.mcpb` free of agent-doc entries) and an identity check (`name`/`title`/manifest `display_name` equal the unscoped package name).
|
|
20
|
+
- **`check-framework-antipatterns`** — adds a `z.coerce.boolean()` env-flag rule (`Boolean("false")` is `true` — use `z.stringbool()`) and skips comment lines so documented mentions don't trip the scan.
|
|
21
|
+
- **`.mcpbignore`** — root dev-dir patterns anchored with a leading `/`; `.agents/` and `skills/` added.
|
|
22
|
+
- **Skill sync** — vendored skills resynced to the framework version; `add-export`, `add-provider`, and `techniques` added; `skills/README.md` added.
|
|
23
|
+
- **`hono` ^4.12.23 → ^4.12.25**, **`@types/node` ^25.9.1 → ^25.9.3**.
|
|
24
|
+
- **`typescript` ^6.0.3 → ^5.9.3** — pinned to 5.x (TS 6 not yet adopted); allowlisted in `devcheck` outdated.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "@cyanheads/mcp-ts-core ^0.10.6 → ^0.10.9 — check-dependency-specifiers + plugin-manifest devcheck guards, ctx.content collector, canvas SQL gate classification; dropped unused direct hono dependency; TypeScript 6 adopted"
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.5.11 — 2026-06-20
|
|
8
|
+
|
|
9
|
+
## Changed
|
|
10
|
+
|
|
11
|
+
- **`@cyanheads/mcp-ts-core` ^0.10.6 → ^0.10.9** — framework adoption. Brings the `check-dependency-specifiers` devcheck step (rejects floating `latest`/`*`/dist-tag specifiers in `package.json` and `bun.lock`'s `workspaces` map), `lint:packaging` check 10 (validates `.claude-plugin`/`.codex-plugin` manifest descriptions, unscoped display identity, and full-name `npx -y` install args), the `ctx.content` collector for image/audio blocks, sharper canvas SQL gate classification (`SELECT`-shaped prepare failures now throw `invalid_sql` with DuckDB binder detail), fresh-scaffold guards in `build-changelog`/`devcheck`, a `check-skill-versions` worktree-deletion guard, and the `DuckdbProvider.describe()` filter-qualification fix.
|
|
12
|
+
- **`devcheck.config.json`** — added `packaging.pluginManifests: true` to opt into the new plugin-manifest checks.
|
|
13
|
+
- **`.codex-plugin/plugin.json`** — populated the previously empty `interface.longDescription`.
|
|
14
|
+
- **Skill sync** — vendored `skills/` resynced to the framework version (14 updated); `add-export` and `add-provider` pruned (removed upstream); `scripts/` maintenance helpers re-synced, adding `scripts/check-dependency-specifiers.ts`.
|
|
15
|
+
- **`typescript` ^5.9.3 → ^6.0.3** — TypeScript 6 adopted (reverses the 0.5.10 hold).
|
|
16
|
+
|
|
17
|
+
## Removed
|
|
18
|
+
|
|
19
|
+
- **Unused direct `hono` dependency** — dropped from `package.json`. It was unused in source and escalated a transitive `hono` advisory into a false direct-dependency security-audit failure; `hono` remains available transitively via `@cyanheads/mcp-ts-core`.
|
|
20
|
+
|
|
21
|
+
### Dependency bumps
|
|
22
|
+
|
|
23
|
+
- `@cyanheads/mcp-ts-core` ^0.10.6 → ^0.10.9
|
|
24
|
+
- `@biomejs/biome` ^2.4.16 → ^2.5.0
|
|
25
|
+
- `@types/node` ^25.9.3 → ^26.0.0
|
|
26
|
+
- `typescript` ^5.9.3 → ^6.0.3
|
|
27
|
+
- `vitest` ^4.1.8 → ^4.1.9
|