@cyanheads/hn-mcp-server 0.5.21 → 0.6.0
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/AGENTS.md +26 -10
- package/CLAUDE.md +26 -10
- package/Dockerfile +10 -4
- package/README.md +31 -19
- package/changelog/0.5.x/0.5.22.md +45 -0
- package/changelog/0.6.x/0.6.0.md +38 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp-server/tools/definitions/get-stories.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/get-stories.tool.js +31 -17
- package/dist/mcp-server/tools/definitions/get-stories.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/get-thread.tool.d.ts +4 -2
- package/dist/mcp-server/tools/definitions/get-thread.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/get-thread.tool.js +427 -220
- package/dist/mcp-server/tools/definitions/get-thread.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/get-user.tool.d.ts +1 -0
- package/dist/mcp-server/tools/definitions/get-user.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/get-user.tool.js +176 -106
- package/dist/mcp-server/tools/definitions/get-user.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/search-content.tool.d.ts +106 -0
- package/dist/mcp-server/tools/definitions/search-content.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/search-content.tool.js +532 -194
- package/dist/mcp-server/tools/definitions/search-content.tool.js.map +1 -1
- package/dist/mcp-server/tools/response-budget.d.ts +111 -0
- package/dist/mcp-server/tools/response-budget.d.ts.map +1 -0
- package/dist/mcp-server/tools/response-budget.js +204 -0
- package/dist/mcp-server/tools/response-budget.js.map +1 -0
- package/dist/mcp-server/tools/served-at-cap.d.ts +14 -0
- package/dist/mcp-server/tools/served-at-cap.d.ts.map +1 -0
- package/dist/mcp-server/tools/served-at-cap.js +16 -0
- package/dist/mcp-server/tools/served-at-cap.js.map +1 -0
- package/dist/mcp-server/tools/thread-cursor.d.ts +68 -0
- package/dist/mcp-server/tools/thread-cursor.d.ts.map +1 -0
- package/dist/mcp-server/tools/thread-cursor.js +200 -0
- package/dist/mcp-server/tools/thread-cursor.js.map +1 -0
- package/dist/services/hn/hn-service.d.ts +73 -12
- package/dist/services/hn/hn-service.d.ts.map +1 -1
- package/dist/services/hn/hn-service.js +127 -38
- package/dist/services/hn/hn-service.js.map +1 -1
- package/dist/services/hn/types.d.ts +9 -0
- package/dist/services/hn/types.d.ts.map +1 -1
- package/package.json +13 -12
- package/server.json +3 -3
- package/skills/hn-guide/SKILL.md +39 -0
|
@@ -4,6 +4,67 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { z } from '@cyanheads/mcp-ts-core';
|
|
6
6
|
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
7
|
+
/**
|
|
8
|
+
* Drop the scheme and `www.` from a query that is a URL alone. Algolia requires
|
|
9
|
+
* every token, so `https` and `www` would otherwise have to appear in the
|
|
10
|
+
* submitted URL, and the same page submitted under the other scheme or without
|
|
11
|
+
* `www.` would drop out. A query with whitespace is searched as typed, and so
|
|
12
|
+
* is one the prefix would leave empty.
|
|
13
|
+
*/
|
|
14
|
+
export declare function stripUrlPrefix(query: string): {
|
|
15
|
+
query: string;
|
|
16
|
+
droppedPrefix?: string;
|
|
17
|
+
};
|
|
18
|
+
/** What the search notice is composed from: the inputs as searched, and the page Algolia returned. */
|
|
19
|
+
export interface SearchNoticeFacts {
|
|
20
|
+
author?: string | undefined;
|
|
21
|
+
/** How a full page over the response budget was fitted to it; absent for a page that fit. */
|
|
22
|
+
budget?: SearchBudget | undefined;
|
|
23
|
+
count: number;
|
|
24
|
+
dateRange?: {
|
|
25
|
+
start?: string | undefined;
|
|
26
|
+
end?: string | undefined;
|
|
27
|
+
} | undefined;
|
|
28
|
+
/** The URL prefix dropped from the caller's query before searching. */
|
|
29
|
+
droppedPrefix?: string | undefined;
|
|
30
|
+
minPoints?: number | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* The caller's count and page when count was above the per-call cap. The
|
|
33
|
+
* search then ran at `count` (the cap) and `page` (the page at the cap where
|
|
34
|
+
* the requested page starts), which the other facts describe.
|
|
35
|
+
*/
|
|
36
|
+
overCap?: {
|
|
37
|
+
count: number;
|
|
38
|
+
page: number;
|
|
39
|
+
} | undefined;
|
|
40
|
+
page: number;
|
|
41
|
+
/** The query sent to Algolia; absent for a filter-only search. */
|
|
42
|
+
query?: string | undefined;
|
|
43
|
+
/** Hits on this page. */
|
|
44
|
+
shown: number;
|
|
45
|
+
storyId?: number | undefined;
|
|
46
|
+
tags?: string | undefined;
|
|
47
|
+
totalHits: number;
|
|
48
|
+
/** False when totalHits is an estimate; undefined when Algolia does not say. */
|
|
49
|
+
totalHitsExact?: boolean | undefined;
|
|
50
|
+
totalPages: number;
|
|
51
|
+
}
|
|
52
|
+
/** The two steps that fit a full page over the response budget to it. */
|
|
53
|
+
interface SearchBudget {
|
|
54
|
+
/** Ids of the hits step 2 cut the text of, in page order; empty when step 1 sufficed. */
|
|
55
|
+
cutIds: readonly number[];
|
|
56
|
+
/** Step 1 dropped highlights.text from every hit. False when no hit carried one. */
|
|
57
|
+
highlightsTextOmitted: boolean;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Compose the one `notice` string every search writes. `notice` is last-wins,
|
|
61
|
+
* so each source goes through here: the page-state sentence first, then the
|
|
62
|
+
* cause sentences in input order — query, tags, author, storyId, count — then
|
|
63
|
+
* the budget sentence for a page fitted to the response budget. None replaces
|
|
64
|
+
* another. Undefined when nothing applies — the last page of an uncapped,
|
|
65
|
+
* non-empty search that fit.
|
|
66
|
+
*/
|
|
67
|
+
export declare function composeSearchNotice(facts: SearchNoticeFacts): string | undefined;
|
|
7
68
|
export declare const searchHn: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
|
|
8
69
|
query: z.ZodOptional<z.ZodString>;
|
|
9
70
|
tags: z.ZodOptional<z.ZodEnum<{
|
|
@@ -35,6 +96,13 @@ export declare const searchHn: import("@cyanheads/mcp-ts-core").ToolDefinition<z
|
|
|
35
96
|
}, z.core.$strip>, z.ZodObject<{
|
|
36
97
|
hits: z.ZodArray<z.ZodObject<{
|
|
37
98
|
id: z.ZodNumber;
|
|
99
|
+
type: z.ZodOptional<z.ZodEnum<{
|
|
100
|
+
comment: "comment";
|
|
101
|
+
job: "job";
|
|
102
|
+
poll: "poll";
|
|
103
|
+
pollopt: "pollopt";
|
|
104
|
+
story: "story";
|
|
105
|
+
}>>;
|
|
38
106
|
title: z.ZodOptional<z.ZodString>;
|
|
39
107
|
url: z.ZodOptional<z.ZodString>;
|
|
40
108
|
domain: z.ZodOptional<z.ZodString>;
|
|
@@ -45,6 +113,7 @@ export declare const searchHn: import("@cyanheads/mcp-ts-core").ToolDefinition<z
|
|
|
45
113
|
storyTitle: z.ZodOptional<z.ZodString>;
|
|
46
114
|
storyId: z.ZodOptional<z.ZodNumber>;
|
|
47
115
|
text: z.ZodOptional<z.ZodString>;
|
|
116
|
+
textTruncated: z.ZodOptional<z.ZodBoolean>;
|
|
48
117
|
highlights: z.ZodOptional<z.ZodObject<{
|
|
49
118
|
title: z.ZodOptional<z.ZodString>;
|
|
50
119
|
text: z.ZodOptional<z.ZodString>;
|
|
@@ -70,6 +139,12 @@ export declare const searchHn: import("@cyanheads/mcp-ts-core").ToolDefinition<z
|
|
|
70
139
|
readonly when: "minPoints was combined with tags \"comment\" or \"job\", record types Algolia stores without points.";
|
|
71
140
|
readonly recovery: "Drop minPoints to search comments or jobs, or search a scored type (story, poll, ask_hn, show_hn, front_page) to filter by points.";
|
|
72
141
|
readonly severity: "notice";
|
|
142
|
+
}, {
|
|
143
|
+
readonly reason: "count_page_unaligned";
|
|
144
|
+
readonly code: JsonRpcErrorCode.InvalidParams;
|
|
145
|
+
readonly when: "count was above the per-call cap of 50 with a page whose first hit (page × count) begins no page of 50 hits, so the requested page cannot be served from its start at the cap.";
|
|
146
|
+
readonly recovery: "Pass a count of 50 or less with page counted in that count; the error names a count and page that start at the same hit and, when that count is under 25, the page of 50 that holds the hit.";
|
|
147
|
+
readonly severity: "notice";
|
|
73
148
|
}, {
|
|
74
149
|
readonly reason: "upstream_rejected";
|
|
75
150
|
readonly code: JsonRpcErrorCode.InvalidParams;
|
|
@@ -105,12 +180,43 @@ export declare const searchHn: import("@cyanheads/mcp-ts-core").ToolDefinition<z
|
|
|
105
180
|
readonly retryable: true;
|
|
106
181
|
readonly thrownBy: "service";
|
|
107
182
|
}], {
|
|
183
|
+
readonly criteria: z.ZodObject<{
|
|
184
|
+
tags: z.ZodOptional<z.ZodEnum<{
|
|
185
|
+
ask_hn: "ask_hn";
|
|
186
|
+
comment: "comment";
|
|
187
|
+
front_page: "front_page";
|
|
188
|
+
job: "job";
|
|
189
|
+
poll: "poll";
|
|
190
|
+
show_hn: "show_hn";
|
|
191
|
+
story: "story";
|
|
192
|
+
}>>;
|
|
193
|
+
author: z.ZodOptional<z.ZodString>;
|
|
194
|
+
storyId: z.ZodOptional<z.ZodNumber>;
|
|
195
|
+
minPoints: z.ZodOptional<z.ZodNumber>;
|
|
196
|
+
dateRange: z.ZodOptional<z.ZodObject<{
|
|
197
|
+
start: z.ZodOptional<z.ZodString>;
|
|
198
|
+
end: z.ZodOptional<z.ZodString>;
|
|
199
|
+
}, z.core.$strip>>;
|
|
200
|
+
sort: z.ZodEnum<{
|
|
201
|
+
date: "date";
|
|
202
|
+
relevance: "relevance";
|
|
203
|
+
}>;
|
|
204
|
+
count: z.ZodNumber;
|
|
205
|
+
view: z.ZodEnum<{
|
|
206
|
+
compact: "compact";
|
|
207
|
+
full: "full";
|
|
208
|
+
}>;
|
|
209
|
+
}, z.core.$strip>;
|
|
108
210
|
readonly totalHits: z.ZodNumber;
|
|
211
|
+
readonly totalHitsExact: z.ZodOptional<z.ZodBoolean>;
|
|
109
212
|
readonly page: z.ZodNumber;
|
|
110
213
|
readonly totalPages: z.ZodNumber;
|
|
214
|
+
readonly reachableHits: z.ZodOptional<z.ZodNumber>;
|
|
111
215
|
readonly truncated: z.ZodOptional<z.ZodBoolean>;
|
|
112
216
|
readonly shown: z.ZodOptional<z.ZodNumber>;
|
|
113
217
|
readonly cap: z.ZodOptional<z.ZodNumber>;
|
|
218
|
+
readonly highlightsTextOmitted: z.ZodOptional<z.ZodBoolean>;
|
|
114
219
|
readonly notice: z.ZodOptional<z.ZodString>;
|
|
115
220
|
}>;
|
|
221
|
+
export {};
|
|
116
222
|
//# sourceMappingURL=search-content.tool.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search-content.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/search-content.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"search-content.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/search-content.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AA+HjE;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,CAKvF;AA0ED,sGAAsG;AACtG,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,6FAA6F;IAC7F,MAAM,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,GAAG,SAAS,CAAC;IACjF,uEAAuE;IACvE,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B;;;;OAIG;IACH,OAAO,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,gFAAgF;IAChF,cAAc,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACrC,UAAU,EAAE,MAAM,CAAC;CACpB;AA8FD,yEAAyE;AACzE,UAAU,YAAY;IACpB,yFAAyF;IACzF,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,oFAAoF;IACpF,qBAAqB,EAAE,OAAO,CAAC;CAChC;AAYD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,GAAG,SAAS,CAOhF;AAmQD,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+XnB,CAAC"}
|