@fre4x/hn 1.0.30 → 1.0.42
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/README.md +10 -1
- package/dist/index.js +24 -17
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -23,6 +23,14 @@ Hacker News is where technologists think out loud. This server taps that stream
|
|
|
23
23
|
|
|
24
24
|
All tools return paginated Markdown or JSON. Token limit enforced at ~3,000 tokens per response.
|
|
25
25
|
|
|
26
|
+
## Mock Mode
|
|
27
|
+
|
|
28
|
+
Run without any API key (returns fixture data of identical shape):
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
MOCK=true npx @fre4x/hn
|
|
32
|
+
```
|
|
33
|
+
|
|
26
34
|
## Deploy
|
|
27
35
|
|
|
28
36
|
```json
|
|
@@ -41,7 +49,8 @@ All tools return paginated Markdown or JSON. Token limit enforced at ~3,000 toke
|
|
|
41
49
|
```bash
|
|
42
50
|
npm install
|
|
43
51
|
npm run dev # tsx, no build
|
|
44
|
-
npm run build #
|
|
52
|
+
npm run build # esbuild → dist/
|
|
53
|
+
npm test # vitest unit tests
|
|
45
54
|
```
|
|
46
55
|
|
|
47
56
|
## License
|
package/dist/index.js
CHANGED
|
@@ -3498,7 +3498,7 @@ var require_schemes = __commonJS({
|
|
|
3498
3498
|
serialize: httpSerialize
|
|
3499
3499
|
}
|
|
3500
3500
|
);
|
|
3501
|
-
var
|
|
3501
|
+
var https3 = (
|
|
3502
3502
|
/** @type {SchemeHandler} */
|
|
3503
3503
|
{
|
|
3504
3504
|
scheme: "https",
|
|
@@ -3547,7 +3547,7 @@ var require_schemes = __commonJS({
|
|
|
3547
3547
|
/** @type {Record<SchemeName, SchemeHandler>} */
|
|
3548
3548
|
{
|
|
3549
3549
|
http: http3,
|
|
3550
|
-
https:
|
|
3550
|
+
https: https3,
|
|
3551
3551
|
ws,
|
|
3552
3552
|
wss,
|
|
3553
3553
|
urn,
|
|
@@ -16763,7 +16763,7 @@ var require_form_data = __commonJS({
|
|
|
16763
16763
|
var util4 = __require("util");
|
|
16764
16764
|
var path = __require("path");
|
|
16765
16765
|
var http3 = __require("http");
|
|
16766
|
-
var
|
|
16766
|
+
var https3 = __require("https");
|
|
16767
16767
|
var parseUrl = __require("url").parse;
|
|
16768
16768
|
var fs = __require("fs");
|
|
16769
16769
|
var Stream = __require("stream").Stream;
|
|
@@ -17032,7 +17032,7 @@ var require_form_data = __commonJS({
|
|
|
17032
17032
|
}
|
|
17033
17033
|
options.headers = this.getHeaders(params.headers);
|
|
17034
17034
|
if (options.protocol === "https:") {
|
|
17035
|
-
request =
|
|
17035
|
+
request = https3.request(options);
|
|
17036
17036
|
} else {
|
|
17037
17037
|
request = http3.request(options);
|
|
17038
17038
|
}
|
|
@@ -17945,7 +17945,7 @@ var require_follow_redirects = __commonJS({
|
|
|
17945
17945
|
var url3 = __require("url");
|
|
17946
17946
|
var URL2 = url3.URL;
|
|
17947
17947
|
var http3 = __require("http");
|
|
17948
|
-
var
|
|
17948
|
+
var https3 = __require("https");
|
|
17949
17949
|
var Writable = __require("stream").Writable;
|
|
17950
17950
|
var assert2 = __require("assert");
|
|
17951
17951
|
var debug = require_debug();
|
|
@@ -18430,7 +18430,7 @@ var require_follow_redirects = __commonJS({
|
|
|
18430
18430
|
function isURL(value) {
|
|
18431
18431
|
return URL2 && value instanceof URL2;
|
|
18432
18432
|
}
|
|
18433
|
-
module.exports = wrap({ http: http3, https:
|
|
18433
|
+
module.exports = wrap({ http: http3, https: https3 });
|
|
18434
18434
|
module.exports.wrap = wrap;
|
|
18435
18435
|
}
|
|
18436
18436
|
});
|
|
@@ -41725,6 +41725,9 @@ var StdioServerTransport = class {
|
|
|
41725
41725
|
}
|
|
41726
41726
|
};
|
|
41727
41727
|
|
|
41728
|
+
// src/api.ts
|
|
41729
|
+
import https2 from "node:https";
|
|
41730
|
+
|
|
41728
41731
|
// ../node_modules/axios/lib/helpers/bind.js
|
|
41729
41732
|
function bind(fn, thisArg) {
|
|
41730
41733
|
return function wrap() {
|
|
@@ -45504,6 +45507,10 @@ var {
|
|
|
45504
45507
|
|
|
45505
45508
|
// src/api.ts
|
|
45506
45509
|
var BASE_URL = "https://hacker-news.firebaseio.com/v0";
|
|
45510
|
+
var httpClient = axios_default.create({
|
|
45511
|
+
baseURL: BASE_URL,
|
|
45512
|
+
httpsAgent: new https2.Agent({ keepAlive: true })
|
|
45513
|
+
});
|
|
45507
45514
|
var HNApiClient = class {
|
|
45508
45515
|
cache = /* @__PURE__ */ new Map();
|
|
45509
45516
|
CACHE_TTL_MS = 60 * 1e3;
|
|
@@ -45518,42 +45525,42 @@ var HNApiClient = class {
|
|
|
45518
45525
|
if (cached2 && Date.now() - cached2.timestamp < this.CACHE_TTL_MS) {
|
|
45519
45526
|
return cached2.data;
|
|
45520
45527
|
}
|
|
45521
|
-
const response = await
|
|
45528
|
+
const response = await httpClient.get(`${url3}.json`);
|
|
45522
45529
|
this.cache.set(url3, { data: response.data, timestamp: Date.now() });
|
|
45523
45530
|
return response.data;
|
|
45524
45531
|
}
|
|
45525
45532
|
async getItem(id) {
|
|
45526
|
-
const response = await
|
|
45533
|
+
const response = await httpClient.get(`/item/${id}.json`);
|
|
45527
45534
|
return response.data;
|
|
45528
45535
|
}
|
|
45529
45536
|
async getUser(id) {
|
|
45530
|
-
const response = await
|
|
45537
|
+
const response = await httpClient.get(`/user/${id}.json`);
|
|
45531
45538
|
return response.data;
|
|
45532
45539
|
}
|
|
45533
45540
|
async getMaxItem() {
|
|
45534
|
-
const response = await
|
|
45541
|
+
const response = await httpClient.get(`/maxitem.json`);
|
|
45535
45542
|
return response.data;
|
|
45536
45543
|
}
|
|
45537
45544
|
async getTopStories() {
|
|
45538
|
-
return this.fetchWithCache(
|
|
45545
|
+
return this.fetchWithCache(`/topstories`);
|
|
45539
45546
|
}
|
|
45540
45547
|
async getNewStories() {
|
|
45541
|
-
return this.fetchWithCache(
|
|
45548
|
+
return this.fetchWithCache(`/newstories`);
|
|
45542
45549
|
}
|
|
45543
45550
|
async getBestStories() {
|
|
45544
|
-
return this.fetchWithCache(
|
|
45551
|
+
return this.fetchWithCache(`/beststories`);
|
|
45545
45552
|
}
|
|
45546
45553
|
async getAskStories() {
|
|
45547
|
-
return this.fetchWithCache(
|
|
45554
|
+
return this.fetchWithCache(`/askstories`);
|
|
45548
45555
|
}
|
|
45549
45556
|
async getShowStories() {
|
|
45550
|
-
return this.fetchWithCache(
|
|
45557
|
+
return this.fetchWithCache(`/showstories`);
|
|
45551
45558
|
}
|
|
45552
45559
|
async getJobStories() {
|
|
45553
|
-
return this.fetchWithCache(
|
|
45560
|
+
return this.fetchWithCache(`/jobstories`);
|
|
45554
45561
|
}
|
|
45555
45562
|
async getUpdates() {
|
|
45556
|
-
const response = await
|
|
45563
|
+
const response = await httpClient.get(`/updates.json`);
|
|
45557
45564
|
return response.data;
|
|
45558
45565
|
}
|
|
45559
45566
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fre4x/hn",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.42",
|
|
4
4
|
"description": "A Hacker News MCP server for LLMs.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
"dist"
|
|
12
12
|
],
|
|
13
13
|
"scripts": {
|
|
14
|
-
"build": "npx esbuild src/index.ts --bundle --outfile=dist/index.js --platform=node --format=esm --banner:js=\"import{createRequire}from'module';const require=createRequire(import.meta.url);\"",
|
|
15
|
-
"typecheck": "NODE_OPTIONS
|
|
14
|
+
"build": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\" && npx esbuild src/index.ts --bundle --outfile=dist/index.js --platform=node --format=esm --banner:js=\"import{createRequire}from'module';const require=createRequire(import.meta.url);\"",
|
|
15
|
+
"typecheck": "cross-env NODE_OPTIONS=--max-old-space-size=4096 tsc --noEmit",
|
|
16
16
|
"start": "node dist/index.js",
|
|
17
17
|
"dev": "tsx src/index.ts",
|
|
18
18
|
"watch": "tsc -w",
|