@cyanheads/gdelt-mcp-server 0.2.1 → 0.2.3

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.
Files changed (45) hide show
  1. package/CLAUDE.md +47 -36
  2. package/Dockerfile +10 -6
  3. package/LICENSE +201 -0
  4. package/README.md +1 -1
  5. package/changelog/0.2.x/0.2.2.md +20 -0
  6. package/changelog/0.2.x/0.2.3.md +44 -0
  7. package/changelog/template.md +5 -3
  8. package/dist/mcp-server/tools/date-range.d.ts +27 -0
  9. package/dist/mcp-server/tools/date-range.d.ts.map +1 -0
  10. package/dist/mcp-server/tools/date-range.js +29 -0
  11. package/dist/mcp-server/tools/date-range.js.map +1 -0
  12. package/dist/mcp-server/tools/definitions/get-coverage-breakdown.tool.d.ts +10 -0
  13. package/dist/mcp-server/tools/definitions/get-coverage-breakdown.tool.d.ts.map +1 -1
  14. package/dist/mcp-server/tools/definitions/get-coverage-breakdown.tool.js +22 -2
  15. package/dist/mcp-server/tools/definitions/get-coverage-breakdown.tool.js.map +1 -1
  16. package/dist/mcp-server/tools/definitions/get-coverage-timeline.tool.d.ts +10 -0
  17. package/dist/mcp-server/tools/definitions/get-coverage-timeline.tool.d.ts.map +1 -1
  18. package/dist/mcp-server/tools/definitions/get-coverage-timeline.tool.js +22 -2
  19. package/dist/mcp-server/tools/definitions/get-coverage-timeline.tool.js.map +1 -1
  20. package/dist/mcp-server/tools/definitions/get-tone-distribution.tool.d.ts +10 -0
  21. package/dist/mcp-server/tools/definitions/get-tone-distribution.tool.d.ts.map +1 -1
  22. package/dist/mcp-server/tools/definitions/get-tone-distribution.tool.js +22 -2
  23. package/dist/mcp-server/tools/definitions/get-tone-distribution.tool.js.map +1 -1
  24. package/dist/mcp-server/tools/definitions/get-tv-clips.tool.d.ts +10 -0
  25. package/dist/mcp-server/tools/definitions/get-tv-clips.tool.d.ts.map +1 -1
  26. package/dist/mcp-server/tools/definitions/get-tv-clips.tool.js +25 -3
  27. package/dist/mcp-server/tools/definitions/get-tv-clips.tool.js.map +1 -1
  28. package/dist/mcp-server/tools/definitions/get-tv-context.tool.d.ts +10 -0
  29. package/dist/mcp-server/tools/definitions/get-tv-context.tool.d.ts.map +1 -1
  30. package/dist/mcp-server/tools/definitions/get-tv-context.tool.js +25 -3
  31. package/dist/mcp-server/tools/definitions/get-tv-context.tool.js.map +1 -1
  32. package/dist/mcp-server/tools/definitions/search-articles.tool.d.ts +10 -0
  33. package/dist/mcp-server/tools/definitions/search-articles.tool.d.ts.map +1 -1
  34. package/dist/mcp-server/tools/definitions/search-articles.tool.js +24 -4
  35. package/dist/mcp-server/tools/definitions/search-articles.tool.js.map +1 -1
  36. package/dist/mcp-server/tools/definitions/search-tv.tool.d.ts +10 -0
  37. package/dist/mcp-server/tools/definitions/search-tv.tool.d.ts.map +1 -1
  38. package/dist/mcp-server/tools/definitions/search-tv.tool.js +26 -5
  39. package/dist/mcp-server/tools/definitions/search-tv.tool.js.map +1 -1
  40. package/dist/services/gdelt/gdelt-fetch.d.ts +8 -0
  41. package/dist/services/gdelt/gdelt-fetch.d.ts.map +1 -1
  42. package/dist/services/gdelt/gdelt-fetch.js +64 -3
  43. package/dist/services/gdelt/gdelt-fetch.js.map +1 -1
  44. package/package.json +10 -8
  45. package/server.json +3 -3
@@ -6,6 +6,7 @@
6
6
  import { tool, z } from '@cyanheads/mcp-ts-core';
7
7
  import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
8
8
  import { getGdeltDocService } from '../../../services/gdelt/gdelt-doc-service.js';
9
+ import { GDELT_DATETIME_PATTERN, isUnpairedDateRange } from '../date-range.js';
9
10
  export const gdeltSearchArticles = tool('gdelt_search_articles', {
10
11
  title: 'Search GDELT Articles',
11
12
  description: 'Search the last 3 months of global news coverage (65+ languages) using the GDELT DOC API. ' +
@@ -22,6 +23,18 @@ export const gdeltSearchArticles = tool('gdelt_search_articles', {
22
23
  when: 'No articles matched the query within the specified time range.',
23
24
  recovery: 'Broaden the query, remove operators, extend timespan, or try synonym terms.',
24
25
  },
26
+ {
27
+ reason: 'invalid_date_range',
28
+ code: JsonRpcErrorCode.ValidationError,
29
+ when: 'Exactly one of startDatetime / endDatetime was supplied.',
30
+ recovery: 'Supply both startDatetime and endDatetime to pin an explicit window, or omit both and use timespan instead.',
31
+ },
32
+ {
33
+ reason: 'invalid_query',
34
+ code: JsonRpcErrorCode.ValidationError,
35
+ when: 'GDELT rejected the query string as malformed — bad keyword length, unbalanced parentheses, or an illegal character.',
36
+ recovery: 'Read the recovery hint for the specific rule GDELT rejected, then fix the query and retry.',
37
+ },
25
38
  {
26
39
  reason: 'gdelt_unavailable',
27
40
  code: JsonRpcErrorCode.ServiceUnavailable,
@@ -44,14 +57,18 @@ export const gdeltSearchArticles = tool('gdelt_search_articles', {
44
57
  'Maximum is 3 months (the full DOC API window). Defaults to the full 3-month window.'),
45
58
  startDatetime: z
46
59
  .string()
60
+ .regex(GDELT_DATETIME_PATTERN, 'startDatetime must be exactly 14 digits (YYYYMMDDHHMMSS).')
47
61
  .optional()
48
- .describe('Start of date range in GDELT format YYYYMMDDHHMMSS (e.g. 20240101000000). ' +
49
- 'Must be used together with endDatetime.'),
62
+ .describe('Start of date range in GDELT format YYYYMMDDHHMMSS exactly 14 digits, no separators ' +
63
+ '(e.g. 20240101000000). Must be supplied together with endDatetime; supplying only one ' +
64
+ 'of the two is rejected.'),
50
65
  endDatetime: z
51
66
  .string()
67
+ .regex(GDELT_DATETIME_PATTERN, 'endDatetime must be exactly 14 digits (YYYYMMDDHHMMSS).')
52
68
  .optional()
53
- .describe('End of date range in GDELT format YYYYMMDDHHMMSS (e.g. 20240131235959). ' +
54
- 'Must be used together with startDatetime.'),
69
+ .describe('End of date range in GDELT format YYYYMMDDHHMMSS exactly 14 digits, no separators ' +
70
+ '(e.g. 20240131235959). Must be supplied together with startDatetime; supplying only one ' +
71
+ 'of the two is rejected.'),
55
72
  maxRecords: z
56
73
  .number()
57
74
  .int()
@@ -99,6 +116,9 @@ export const gdeltSearchArticles = tool('gdelt_search_articles', {
99
116
  .describe('Recovery hint when no articles matched — echoes filters and suggests how to broaden. Absent on successful responses.'),
100
117
  },
101
118
  async handler(input, ctx) {
119
+ if (isUnpairedDateRange(input.startDatetime, input.endDatetime)) {
120
+ throw ctx.fail('invalid_date_range', 'startDatetime and endDatetime must be supplied together', ctx.recoveryFor('invalid_date_range'));
121
+ }
102
122
  ctx.log.info('gdelt_search_articles', { query: input.query });
103
123
  const svc = getGdeltDocService();
104
124
  const result = await svc.searchArticles({
@@ -1 +1 @@
1
- {"version":3,"file":"search-articles.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/search-articles.tool.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"search-articles.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/search-articles.tool.ts"],"names":[],"mappings":"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"}
@@ -36,6 +36,16 @@ export declare const gdeltSearchTv: import("@cyanheads/mcp-ts-core").ToolDefinit
36
36
  readonly code: JsonRpcErrorCode.NotFound;
37
37
  readonly when: "No TV coverage found for the query in the specified time range.";
38
38
  readonly recovery: string;
39
+ }, {
40
+ readonly reason: "invalid_date_range";
41
+ readonly code: JsonRpcErrorCode.ValidationError;
42
+ readonly when: "Exactly one of startDatetime / endDatetime was supplied.";
43
+ readonly recovery: "Supply both startDatetime and endDatetime to pin an explicit window, or omit both and use timespan instead.";
44
+ }, {
45
+ readonly reason: "invalid_query";
46
+ readonly code: JsonRpcErrorCode.ValidationError;
47
+ readonly when: "GDELT rejected the query — no station was selected, or the query string is malformed.";
48
+ readonly recovery: "Read the recovery hint for the specific rule GDELT rejected; when no station was selected, list valid IDs with gdelt_list_tv_stations.";
39
49
  }, {
40
50
  readonly reason: "gdelt_unavailable";
41
51
  readonly code: JsonRpcErrorCode.ServiceUnavailable;
@@ -1 +1 @@
1
- {"version":3,"file":"search-tv.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/search-tv.tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAIjE,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6LxB,CAAC"}
1
+ {"version":3,"file":"search-tv.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/search-tv.tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAKjE,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4NxB,CAAC"}
@@ -7,12 +7,13 @@ import { tool, z } from '@cyanheads/mcp-ts-core';
7
7
  import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
8
8
  import { formatDateShort, resolveTimespan } from '../../../services/gdelt/gdelt-fetch.js';
9
9
  import { getGdeltTvService } from '../../../services/gdelt/gdelt-tv-service.js';
10
+ import { GDELT_DATETIME_PATTERN, isUnpairedDateRange } from '../date-range.js';
10
11
  export const gdeltSearchTv = tool('gdelt_search_tv', {
11
12
  title: 'Search GDELT TV News',
12
13
  description: 'Search US television news closed captions (2009–October 2024, 150+ stations) for spoken mentions ' +
13
14
  'of a query. Returns a normalized per-station time series showing relative airtime devoted to the topic. ' +
14
- 'Use the stations parameter to compare specific networks (e.g. ["CNN", "FOXNEWS", "MSNBC"]); ' +
15
- 'omit to get combined national coverage. ' +
15
+ 'Use the stations parameter to select networks (e.g. ["CNN", "FOXNEWS", "MSNBC"]) — the TV API ' +
16
+ 'requires at least one station, supplied either there or as a station: selector inside query. ' +
16
17
  'TV query also supports in-query operators: station:CNN, network:CBS, market:"National", ' +
17
18
  'show:"Anderson Cooper 360", context:"vaccine". ' +
18
19
  'Important: most station monitoring ended October 2024 — use gdelt_list_tv_stations to verify ' +
@@ -26,6 +27,18 @@ export const gdeltSearchTv = tool('gdelt_search_tv', {
26
27
  recovery: 'Check that the stations were active during the time range using gdelt_list_tv_stations, ' +
27
28
  'broaden the query, or extend the timespan.',
28
29
  },
30
+ {
31
+ reason: 'invalid_date_range',
32
+ code: JsonRpcErrorCode.ValidationError,
33
+ when: 'Exactly one of startDatetime / endDatetime was supplied.',
34
+ recovery: 'Supply both startDatetime and endDatetime to pin an explicit window, or omit both and use timespan instead.',
35
+ },
36
+ {
37
+ reason: 'invalid_query',
38
+ code: JsonRpcErrorCode.ValidationError,
39
+ when: 'GDELT rejected the query — no station was selected, or the query string is malformed.',
40
+ recovery: 'Read the recovery hint for the specific rule GDELT rejected; when no station was selected, list valid IDs with gdelt_list_tv_stations.',
41
+ },
29
42
  {
30
43
  reason: 'gdelt_unavailable',
31
44
  code: JsonRpcErrorCode.ServiceUnavailable,
@@ -45,7 +58,8 @@ export const gdeltSearchTv = tool('gdelt_search_tv', {
45
58
  .array(z.string())
46
59
  .optional()
47
60
  .describe('Station IDs to filter to (e.g. ["CNN", "FOXNEWS", "MSNBC"]). ' +
48
- 'Omit to get coverage across all available stations. ' +
61
+ 'The GDELT TV API requires at least one station — supply it here, or embed a station: ' +
62
+ 'selector directly in query. Omitting both is rejected; it does not fall back to all stations. ' +
49
63
  'Use gdelt_list_tv_stations to see valid station IDs.'),
50
64
  timespan: z
51
65
  .string()
@@ -55,12 +69,16 @@ export const gdeltSearchTv = tool('gdelt_search_tv', {
55
69
  'TV data spans 2009–October 2024.'),
56
70
  startDatetime: z
57
71
  .string()
72
+ .regex(GDELT_DATETIME_PATTERN, 'startDatetime must be exactly 14 digits (YYYYMMDDHHMMSS).')
58
73
  .optional()
59
- .describe('Start datetime in GDELT format YYYYMMDDHHMMSS. Must pair with endDatetime.'),
74
+ .describe('Start datetime in GDELT format YYYYMMDDHHMMSS exactly 14 digits, no separators ' +
75
+ '(e.g. 20200101000000). Must pair with endDatetime; supplying only one of the two is rejected.'),
60
76
  endDatetime: z
61
77
  .string()
78
+ .regex(GDELT_DATETIME_PATTERN, 'endDatetime must be exactly 14 digits (YYYYMMDDHHMMSS).')
62
79
  .optional()
63
- .describe('End datetime in GDELT format YYYYMMDDHHMMSS. Must pair with startDatetime.'),
80
+ .describe('End datetime in GDELT format YYYYMMDDHHMMSS exactly 14 digits, no separators ' +
81
+ '(e.g. 20200131235959). Must pair with startDatetime; supplying only one of the two is rejected.'),
64
82
  smoothing: z
65
83
  .number()
66
84
  .int()
@@ -112,6 +130,9 @@ export const gdeltSearchTv = tool('gdelt_search_tv', {
112
130
  .describe('Recovery hint when no TV coverage was found. Absent on successful responses.'),
113
131
  },
114
132
  async handler(input, ctx) {
133
+ if (isUnpairedDateRange(input.startDatetime, input.endDatetime)) {
134
+ throw ctx.fail('invalid_date_range', 'startDatetime and endDatetime must be supplied together', ctx.recoveryFor('invalid_date_range'));
135
+ }
115
136
  ctx.log.info('gdelt_search_tv', { query: input.query, stations: input.stations });
116
137
  const svc = getGdeltTvService();
117
138
  const result = await svc.searchTv({
@@ -1 +1 @@
1
- {"version":3,"file":"search-tv.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/search-tv.tool.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"search-tv.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/search-tv.tool.ts"],"names":[],"mappings":"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"}
@@ -19,4 +19,12 @@ export declare function resolveTimespan(timespan: string): {
19
19
  export declare function formatDateShort(d: Date): string;
20
20
  /** Fetch a GDELT endpoint with rate-limiting, retries, and JSON parsing. */
21
21
  export declare function gdeltFetch<T>(baseUrl: string, params: URLSearchParams, ctx: Context, operation: string, apiLabel: string): Promise<T>;
22
+ /**
23
+ * Parse a GDELT response body, classifying the non-JSON bodies GDELT returns for
24
+ * upstream trouble (HTML, empty) and caller-side query rejections (see
25
+ * `GDELT_REJECTIONS`) before falling back to a generic serialization failure.
26
+ *
27
+ * Exported for direct testing — production callers reach it through `gdeltFetch`.
28
+ */
29
+ export declare function parseGdeltJson<T>(text: string, apiLabel: string): T;
22
30
  //# sourceMappingURL=gdelt-fetch.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"gdelt-fetch.d.ts","sourceRoot":"","sources":["../../../src/services/gdelt/gdelt-fetch.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAKtD,2DAA2D;AAC3D,wBAAgB,cAAc,CAC5B,MAAM,EAAE,eAAe,EACvB,QAAQ,CAAC,EAAE,MAAM,EACjB,aAAa,CAAC,EAAE,MAAM,EACtB,WAAW,CAAC,EAAE,MAAM,GACnB,IAAI,CAON;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,GAAG,EAAE,IAAI,CAAA;CAAE,GAAG,SAAS,CAyBxF;AAED,8DAA8D;AAC9D,wBAAgB,eAAe,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM,CAE/C;AAED,4EAA4E;AAC5E,wBAAgB,UAAU,CAAC,CAAC,EAC1B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,eAAe,EACvB,GAAG,EAAE,OAAO,EACZ,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,CAAC,CAAC,CAcZ"}
1
+ {"version":3,"file":"gdelt-fetch.d.ts","sourceRoot":"","sources":["../../../src/services/gdelt/gdelt-fetch.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAStD,2DAA2D;AAC3D,wBAAgB,cAAc,CAC5B,MAAM,EAAE,eAAe,EACvB,QAAQ,CAAC,EAAE,MAAM,EACjB,aAAa,CAAC,EAAE,MAAM,EACtB,WAAW,CAAC,EAAE,MAAM,GACnB,IAAI,CAON;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,GAAG,EAAE,IAAI,CAAA;CAAE,GAAG,SAAS,CAyBxF;AAED,8DAA8D;AAC9D,wBAAgB,eAAe,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM,CAE/C;AAED,4EAA4E;AAC5E,wBAAgB,UAAU,CAAC,CAAC,EAC1B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,eAAe,EACvB,GAAG,EAAE,OAAO,EACZ,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,CAAC,CAAC,CAcZ;AAyDD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC,CA2BnE"}
@@ -3,7 +3,7 @@
3
3
  * retries, HTML error detection, and JSON parsing.
4
4
  * @module services/gdelt/gdelt-fetch
5
5
  */
6
- import { serializationError, serviceUnavailable } from '@cyanheads/mcp-ts-core/errors';
6
+ import { serializationError, serviceUnavailable, validationError, } from '@cyanheads/mcp-ts-core/errors';
7
7
  import { fetchWithTimeout, withRetry } from '@cyanheads/mcp-ts-core/utils';
8
8
  import { getRateLimiter } from './rate-limiter.js';
9
9
  /** Apply timespan or explicit date range to URL params. */
@@ -65,7 +65,62 @@ export function gdeltFetch(baseUrl, params, ctx, operation, apiLabel) {
65
65
  return parseGdeltJson(text, apiLabel);
66
66
  }, { operation, context: rctx, baseDelayMs: 5100, signal: ctx.signal });
67
67
  }
68
- function parseGdeltJson(text, apiLabel) {
68
+ /**
69
+ * Number of leading characters scanned for a rejection marker, and the length of
70
+ * the body excerpt echoed in error messages. GDELT's rejection bodies are single
71
+ * short sentences, so a bounded prefix is enough to classify them.
72
+ */
73
+ const BODY_EXCERPT_LIMIT = 200;
74
+ /**
75
+ * GDELT query-validation rejections, keyed by a distinctive substring of the body.
76
+ *
77
+ * GDELT serves these as **HTTP 200** with `Content-Type: text/html` despite the body
78
+ * being a bare plain-text sentence, so neither `fetchWithTimeout` (which throws only
79
+ * on non-2xx) nor the `<!DOCTYPE`/`<html` prefix check above catches them — they land
80
+ * in `JSON.parse` and would otherwise surface as a server-fault SerializationError for
81
+ * what is really invalid caller input.
82
+ *
83
+ * Matching is deliberately an enumerated marker list rather than a blanket
84
+ * "non-JSON 200 means bad input" rule: a truncated or genuinely broken upstream body
85
+ * is also a non-JSON 200, and must stay on the SerializationError path instead of
86
+ * being misreported to the caller as their fault. Extend this list as new rejection
87
+ * phrasings are confirmed against the live API.
88
+ */
89
+ const GDELT_REJECTIONS = [
90
+ {
91
+ marker: 'must contain at least one station',
92
+ hint: 'The GDELT TV API requires at least one station. Supply the stations parameter, or embed a ' +
93
+ 'station: selector in the query — use gdelt_list_tv_stations to find valid station IDs.',
94
+ },
95
+ {
96
+ marker: 'too short or too long',
97
+ hint: 'GDELT rejected a keyword for its length — single characters are too short. Use a longer, ' +
98
+ 'more specific keyword, or quote a multi-word phrase such as "bird flu".',
99
+ },
100
+ {
101
+ marker: 'parenthetical clauses had an error',
102
+ hint: 'A parenthetical clause is malformed. Balance every opening parenthesis with a closing one, ' +
103
+ 'e.g. (flu OR pandemic).',
104
+ },
105
+ {
106
+ marker: 'illegal character',
107
+ hint: 'A keyword contains a character GDELT reserves. Wrap the term in double quotes to use it ' +
108
+ 'literally, e.g. "f-16".',
109
+ },
110
+ ];
111
+ /** Recovery hint for the GDELT rejection matching a non-JSON response body, if any. */
112
+ function matchGdeltRejectionHint(text) {
113
+ const head = text.slice(0, BODY_EXCERPT_LIMIT).toLowerCase();
114
+ return GDELT_REJECTIONS.find((rejection) => head.includes(rejection.marker))?.hint;
115
+ }
116
+ /**
117
+ * Parse a GDELT response body, classifying the non-JSON bodies GDELT returns for
118
+ * upstream trouble (HTML, empty) and caller-side query rejections (see
119
+ * `GDELT_REJECTIONS`) before falling back to a generic serialization failure.
120
+ *
121
+ * Exported for direct testing — production callers reach it through `gdeltFetch`.
122
+ */
123
+ export function parseGdeltJson(text, apiLabel) {
69
124
  if (/^\s*<(!DOCTYPE\s+html|html[\s>])/i.test(text)) {
70
125
  throw serviceUnavailable(`${apiLabel} API returned HTML — likely rate-limited or unavailable. Retry after 5 seconds.`);
71
126
  }
@@ -76,7 +131,13 @@ function parseGdeltJson(text, apiLabel) {
76
131
  return JSON.parse(text);
77
132
  }
78
133
  catch {
79
- throw serializationError(`${apiLabel} API returned unparseable response: ${text.slice(0, 200)}`);
134
+ const hint = matchGdeltRejectionHint(text);
135
+ if (hint) {
136
+ // ValidationError is outside withRetry's transient set, so this fails fast
137
+ // instead of replaying a query GDELT will reject identically every time.
138
+ throw validationError(`${apiLabel} API rejected the query: ${text.trim().slice(0, BODY_EXCERPT_LIMIT)}`, { reason: 'invalid_query', recovery: { hint } });
139
+ }
140
+ throw serializationError(`${apiLabel} API returned unparseable response: ${text.slice(0, BODY_EXCERPT_LIMIT)}`);
80
141
  }
81
142
  }
82
143
  //# sourceMappingURL=gdelt-fetch.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"gdelt-fetch.js","sourceRoot":"","sources":["../../../src/services/gdelt/gdelt-fetch.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"gdelt-fetch.js","sourceRoot":"","sources":["../../../src/services/gdelt/gdelt-fetch.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cyanheads/gdelt-mcp-server",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "description": "Search and analyze global news coverage and US television transcripts via the GDELT Project's real-time APIs via MCP. STDIO or Streamable HTTP.",
5
5
  "mcpName": "io.github.cyanheads/gdelt-mcp-server",
6
6
  "type": "module",
@@ -65,7 +65,7 @@
65
65
  "url": "https://github.com/cyanheads/gdelt-mcp-server/issues"
66
66
  },
67
67
  "homepage": "https://github.com/cyanheads/gdelt-mcp-server#readme",
68
- "author": "cyanheads <casey@caseyjhand.com> (https://github.com/cyanheads/gdelt-mcp-server#readme)",
68
+ "author": "Casey Hand <casey@caseyjhand.com> (https://caseyjhand.com)",
69
69
  "funding": [
70
70
  {
71
71
  "type": "github",
@@ -77,6 +77,7 @@
77
77
  }
78
78
  ],
79
79
  "license": "Apache-2.0",
80
+ "packageManager": "bun@1.3.14",
80
81
  "engines": {
81
82
  "bun": ">=1.3.0",
82
83
  "node": ">=24.0.0"
@@ -85,17 +86,18 @@
85
86
  "access": "public"
86
87
  },
87
88
  "dependencies": {
88
- "@cyanheads/mcp-ts-core": "^0.10.6",
89
+ "@cyanheads/mcp-ts-core": "^0.10.14",
89
90
  "pino-pretty": "^13.1.3",
90
91
  "zod": "^4.4.3"
91
92
  },
92
93
  "devDependencies": {
93
- "@biomejs/biome": "^2.4.16",
94
- "@types/node": "^25.9.3",
94
+ "@biomejs/biome": "^2.5.0",
95
+ "@socketsecurity/bun-security-scanner": "^1.1.2",
96
+ "@types/node": "^26.1.1",
95
97
  "depcheck": "^1.4.7",
96
- "ignore": "^7.0.5",
97
- "tsc-alias": "^1.8.17",
98
+ "ignore": "^7.0.6",
99
+ "tsc-alias": "^1.9.0",
98
100
  "typescript": "^6.0.3",
99
- "vitest": "^4.1.8"
101
+ "vitest": "^4.1.10"
100
102
  }
101
103
  }
package/server.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "url": "https://github.com/cyanheads/gdelt-mcp-server",
7
7
  "source": "github"
8
8
  },
9
- "version": "0.2.1",
9
+ "version": "0.2.3",
10
10
  "remotes": [
11
11
  {
12
12
  "type": "streamable-http",
@@ -19,7 +19,7 @@
19
19
  "registryBaseUrl": "https://registry.npmjs.org",
20
20
  "identifier": "@cyanheads/gdelt-mcp-server",
21
21
  "runtimeHint": "node",
22
- "version": "0.2.1",
22
+ "version": "0.2.3",
23
23
  "packageArguments": [
24
24
  {
25
25
  "type": "positional",
@@ -48,7 +48,7 @@
48
48
  "registryBaseUrl": "https://registry.npmjs.org",
49
49
  "identifier": "@cyanheads/gdelt-mcp-server",
50
50
  "runtimeHint": "node",
51
- "version": "0.2.1",
51
+ "version": "0.2.3",
52
52
  "packageArguments": [
53
53
  {
54
54
  "type": "positional",