# io.github.cyanheads/gdelt-mcp-server (remote · gdelt.caseyjhand.com)

Search and analyze global news coverage and US TV transcripts via the GDELT Project APIs.

- Trust score: 67/100 (medium)
- Change this week: +5
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-08-03

## Components

- remote · `gdelt.caseyjhand.com`: 67/100 (this document), [markdown](https://verifymcp.io/servers/cyanheads-gdelt-mcp-server/gdelt.md), [page](https://verifymcp.io/servers/cyanheads-gdelt-mcp-server/gdelt)
- npm · `@cyanheads/gdelt-mcp-server`: 35/100, [markdown](https://verifymcp.io/servers/cyanheads-gdelt-mcp-server/cyanheads-gdelt-mcp-server.md), [page](https://verifymcp.io/servers/cyanheads-gdelt-mcp-server/cyanheads-gdelt-mcp-server)

## Channel facts

- Endpoint: `https://gdelt.caseyjhand.com/mcp`
- Transports: `streamable-http`
- Auth: `none`
- Version: `0.2.6`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-08-03.

- **Endpoint Security**: 66/100
  - The endpoint's TLS certificate is valid, in date, and uses a strong key.
  - Authorisation not fully verified: no authorisation is required to call this server, and 9 tool(s) never declared a destructiveHint. The MCP spec treats an absent hint as destructive by default, so we cannot call this surface safe.
  - HTTPS is enforced; there's no plaintext access path.
  - The HSTS (Strict-Transport-Security) header is present.
  - DNSSEC is configured correctly; the domain's records validate against the full chain to the root.
- **Transport & Reachability**: 100/100
  - Verified streamable-http transport via a live MCP handshake.
- **Schema Quality & AI Usability**: 60/100
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 3745 tokens (~416/item across 9 items; 9 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 27/100
  - Stability observed for 8 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 100/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 100% of tool parameters carry a description.
  - Structured output schemas are declared (100% of tools); any adoption earns full credit.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

### Claude

```bash
claude mcp add --transport http cyanheads-gdelt-mcp-server https://gdelt.caseyjhand.com/mcp
```

### Codex

```toml
[mcp_servers.cyanheads-gdelt-mcp-server]
url = "https://gdelt.caseyjhand.com/mcp"
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "cyanheads-gdelt-mcp-server": {
      "type": "remote",
      "url": "https://gdelt.caseyjhand.com/mcp",
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add cyanheads-gdelt-mcp-server --url https://gdelt.caseyjhand.com/mcp --transport streamable-http
```

### Hermes

```yaml
mcp_servers:
  cyanheads-gdelt-mcp-server:
    url: "https://gdelt.caseyjhand.com/mcp"
```

### Other

```json
{
  "mcpServers": {
    "cyanheads-gdelt-mcp-server": {
      "type": "http",
      "url": "https://gdelt.caseyjhand.com/mcp"
    }
  }
}
```

The mcpServers block is a cross-client convention. Remote transports vary, so check your client's docs.

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-08-02 (score 67, +1)

No change was recorded against any check on this day. Stability & Change Management went from 20 to 23. That category is still filling its 30-day observation window: 6 days of observed history at the previous scan, 7 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-07-31 (score 66, +2)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-30 (score 64, 0)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-29 (score 64, +1)

No change was recorded against any check on this day. Stability & Change Management went from 7 to 10. That category is still filling its 30-day observation window: 2 days of observed history at the previous scan, 3 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-07-28 (score 63, +1)

No change was recorded against any check on this day. Stability & Change Management went from 3 to 7. That category is still filling its 30-day observation window: 1 days of observed history at the previous scan, 2 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-07-27 (score 62, 0)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-26 (score 62)

First indexed and scored.

## MCP tools (9)

### `gdelt_search_articles` (~543 tokens)

Search GDELT Articles

Search the last 3 months of global news coverage (65+ languages) using the GDELT DOC API. Returns up to 250 articles with URL, title, source domain, language, country, publication date, and social image URL. Query supports full GDELT syntax: phrases ("bird flu"), boolean OR ((flu OR pandemic)), source country (sourcecountry:china), source language (sourcelang:spanish), domain (domain:who.int), GKG theme (theme:DISEASE_OUTBREAK), tone filter (tone<-5 for negative), proximity (near20:"flu virus"), and repeat (repeat3:"outbreak"). 250 is a hard per-call ceiling and GDELT offers no cursor: when a query fills it, split the run into narrower startDatetime/endDatetime windows — the response hands back the exact windows to use. Note: this API covers only the most recent 3 months — use gdelt_search_tv for historical TV transcripts back to 2009.

Input parameters:

- `endDatetime` (string): End of date range in GDELT format YYYYMMDDHHMMSS — exactly 14 digits, no separators (e.g. 20240131235959). Must be supplied together with startDatetime; supplying only one of the two is rejected.
- `maxRecords` (integer): Maximum number of articles to return (1–250). 250 is GDELT's hard per-call ceiling, not a page size — there is no cursor past it, so a query that fills 250 must be split into narrower startDatetime/e…
- `query` (string, required): Search query. Supports GDELT operators: phrases ("bird flu"), boolean OR ((flu OR pandemic)), sourcecountry:china, sourcelang:spanish, domain:who.int, theme:DISEASE_OUTBREAK, tone<-5, near20:"flu vir…
- `sort` (string): Sort order: relevance (default), date (newest first), social (most socially shared).
- `startDatetime` (string): Start of date range in GDELT format YYYYMMDDHHMMSS — exactly 14 digits, no separators (e.g. 20240101000000). Must be supplied together with endDatetime; supplying only one of the two is rejected.
- `timespan` (string): Time window relative to now, e.g. "24h", "7d", "1m". Ignored when startDatetime/endDatetime are set. Maximum is 3 months (the full DOC API window). Defaults to the full 3-month window.

Output parameters:

- `articles` (array): Matching articles sorted per the sort parameter.
- `continuationWindows` (array): The queried window halved, to re-run this query against one pair at a time when maxRecords is at its 250 ceiling. The halves overlap by one second so no article falls through the seam; an article pub…
- `effectiveQuery` (string): Echoed query string for use in follow-up calls.
- `notice` (string): Disclosure that the maxRecords cap was reached and more articles may exist, naming the route to them — a higher maxRecords below the 250 ceiling, or a narrower date window at it. Absent when the full…
- `timespan` (string): Echoed timespan parameter when provided.
- `totalCount` (number): Number of articles returned in this response.

### `gdelt_get_coverage_timeline` (~578 tokens)

Get GDELT Coverage Timeline

Retrieve a time series showing when news coverage of a topic spiked, or how average tone shifted over time. Use mode "volume" for normalized coverage intensity (% of all global coverage per timestep). Use mode "volume_with_articles" for the same signal plus the top articles that drove each spike — this is the primary signal-detection mode: a single call reveals both the spike and its cause, avoiding a follow-up gdelt_search_articles call. Use mode "tone" for average sentiment score per timestep (negative = hostile/fearful, positive = celebratory). Date resolution is automatically chosen based on timespan: hours for short windows, days for longer ones. In volume_with_articles mode the text surface shows the first 3 article links per timestep next to that timestep's true article count; name a timestep's date in points to render its full list. Note: DOC API covers only the last 3 months.

Input parameters:

- `endDatetime` (string): End datetime in GDELT format YYYYMMDDHHMMSS — exactly 14 digits, no separators (e.g. 20240131235959). Must pair with startDatetime; supplying only one of the two is rejected.
- `mode` (string): Timeline mode: "volume" returns normalized coverage % per timestep, "volume_with_articles" returns volume plus top articles per spike (best for signal detection), "tone" returns average sentiment sco…
- `points` (array): Timestep dates whose complete article list should be rendered in the text surface, e.g. ["2024-01-05T12:00:00Z"]. Take them verbatim from series[].data[].date in a prior response, or from the list an…
- `query` (string, required): Search query using GDELT syntax. Same operators as gdelt_search_articles: phrases, boolean OR, sourcecountry:, sourcelang:, domain:, theme:, tone<.
- `smoothing` (integer): Smoothing window in timesteps (0 = none, 1–5 = moving average width). Reduces noise for spotty topics.
- `startDatetime` (string): Start datetime in GDELT format YYYYMMDDHHMMSS — exactly 14 digits, no separators (e.g. 20240101000000). Must pair with endDatetime; supplying only one of the two is rejected.
- `timespan` (string): Time window relative to now, e.g. "24h", "7d", "1m". Ignored when startDatetime/endDatetime are set. Maximum 3 months.

Output parameters:

- `dateResolution` (string): Temporal resolution of the data points — hour for short windows, day for longer.
- `effectiveQuery` (string): Echoed query string for use in follow-up calls.
- `endDatetime` (string): Echoed end datetime when provided (YYYYMMDDHHMMSS).
- `expandedPoints` (array): Timestep dates whose full article list is rendered in the text surface instead of the first 3, echoing the points input. Omitted when points was not supplied. Purely a rendering concern — structuredC…
- `mode` (string): Timeline mode used for this response.
- `notice` (string): Recovery hint when no timeline data was returned. Absent on successful responses.
- `series` (array): One or more time series (typically one for volume/tone, one per label for breakdowns).
- `startDatetime` (string): Echoed start datetime when provided (YYYYMMDDHHMMSS).
- `totalCount` (number): Total number of data points across all series.

### `gdelt_get_tone_distribution` (~315 tokens)

Get GDELT Tone Distribution

Get the tonal distribution of articles matching a query as a histogram (bins approximately -30 to +30). Unlike a single average tone score, the histogram reveals whether coverage is uniformly negative, bimodal (some articles extremely positive and some extremely negative), or clustered near neutral. Each bin includes representative article URLs. Distinct from gdelt_get_coverage_timeline (mode: tone) — this is a snapshot distribution across all matching articles, not a time series. Use gdelt_get_coverage_timeline with mode "tone" to see how sentiment shifted over time.

Input parameters:

- `endDatetime` (string): End datetime in GDELT format YYYYMMDDHHMMSS — exactly 14 digits, no separators (e.g. 20240131235959). Must pair with startDatetime; supplying only one of the two is rejected.
- `query` (string, required): Search query using GDELT syntax. Same operators as gdelt_search_articles: phrases, boolean OR, sourcecountry:, sourcelang:, domain:, theme:.
- `startDatetime` (string): Start datetime in GDELT format YYYYMMDDHHMMSS — exactly 14 digits, no separators (e.g. 20240101000000). Must pair with endDatetime; supplying only one of the two is rejected.
- `timespan` (string): Time window relative to now, e.g. "24h", "7d", "1m". Ignored when startDatetime/endDatetime are set. Maximum 3 months.

Output parameters:

- `effectiveQuery` (string): Echoed query string for use in follow-up calls.
- `endDatetime` (string): Echoed end datetime when provided (YYYYMMDDHHMMSS).
- `histogram` (array): Tone histogram sorted from most negative to most positive bin.
- `notice` (string): Recovery hint when no tone data was returned. Absent on successful responses.
- `startDatetime` (string): Echoed start datetime when provided (YYYYMMDDHHMMSS).
- `summary` (object): Summary statistics derived from the histogram.
- `totalCount` (number): Total number of articles across all histogram bins.

### `gdelt_get_coverage_breakdown` (~522 tokens)

Get GDELT Coverage Breakdown

Break down news coverage volume over time by source language or source country, returning a multi-series time series (one series per language or country). Shows which countries or languages drove early vs. late coverage — useful for tracing how a story propagated geographically or across language communities. Returns up to 10 series by total volume and aggregates the rest into an "Other" bucket, naming every series it folded in there under otherSeriesLabels — pass any of those labels back as the series input to get that series complete, ranked or not. Values are normalized: each point is the topic's share of media output, not an absolute article count. Small media markets with concentrated coverage therefore rank above large markets with diverse output — a high value means the topic dominated that source's coverage, not that it published the most articles. Use breakdownBy "country" with the signal-detection chain to map geographic attention, or "language" to detect non-English media surges.

Input parameters:

- `breakdownBy` (string, required): Breakdown dimension: "language" for source language time series, "country" for source country time series.
- `endDatetime` (string): End datetime in GDELT format YYYYMMDDHHMMSS — exactly 14 digits, no separators (e.g. 20240131235959). Must pair with startDatetime; supplying only one of the two is rejected.
- `query` (string, required): Search query using GDELT syntax. Same operators as gdelt_search_articles: phrases, boolean OR, sourcecountry:, sourcelang:, domain:, theme:.
- `series` (array): Exact series labels to additionally return in full, e.g. ["Portuguese", "Vietnamese"]. Take them verbatim from otherSeriesLabels (the series folded into "Other") or topSeries[].label in a response, o…
- `startDatetime` (string): Start datetime in GDELT format YYYYMMDDHHMMSS — exactly 14 digits, no separators (e.g. 20240101000000). Must pair with endDatetime; supplying only one of the two is rejected.
- `timespan` (string): Time window relative to now, e.g. "24h", "7d", "1m". Ignored when startDatetime/endDatetime are set. Maximum 3 months.

Output parameters:

- `breakdownBy` (string): Breakdown dimension used for this response.
- `dateResolution` (string): Temporal resolution of data points.
- `effectiveQuery` (string): Echoed query string for use in follow-up calls.
- `endDatetime` (string): Echoed end datetime when provided (YYYYMMDDHHMMSS).
- `notice` (string): Recovery hint when no breakdown data was returned. Absent on successful responses.
- `otherAggregated` (array): Combined time series for all series beyond the top 10. Omitted when all series fit.
- `otherSeriesLabels` (array): Label of every series folded into otherAggregated, ranked by total volume — the identities the "Other" bucket would otherwise dissolve. Pass any of them to the series input to retrieve that series' c…
- `selectedSeries` (array): Complete, untruncated time series for each label requested via the series input, in the order requested. Omitted when series was not supplied.
- `startDatetime` (string): Echoed start datetime when provided (YYYYMMDDHHMMSS).
- `topSeries` (array): Top 10 series by total coverage volume.
- `totalCount` (number): Total number of series returned before truncation to top 10.

### `gdelt_search_tv` (~502 tokens)

Search GDELT TV News

Search US television news closed captions (2009–October 2024, 150+ stations) for spoken mentions of a query. Returns a normalized per-station time series showing relative airtime devoted to the topic. Use the stations parameter to select networks (e.g. ["CNN", "FOXNEWS", "MSNBC"]) — the TV API requires at least one station, supplied either there or as a station: selector inside query. TV query also supports in-query operators: station:CNN, network:CBS, market:"National", show:"Anderson Cooper 360", context:"vaccine". Important: most station monitoring ended October 2024 — use gdelt_list_tv_stations to verify active date ranges before querying recent events.

Input parameters:

- `endDatetime` (string): End datetime in GDELT format YYYYMMDDHHMMSS — exactly 14 digits, no separators (e.g. 20200131235959). Must pair with startDatetime; supplying only one of the two is rejected.
- `normalize` (boolean): When true (default), values are normalized as % of total airtime, enabling cross-station comparison. When false, returns raw coverage volume.
- `query` (string, required): Search query for TV transcript content. Supports TV operators: station:CNN, network:CBS, market:"National", show:"Anderson Cooper", context:"vaccine". Boolean OR and phrase operators also work.
- `smoothing` (integer): Smoothing window in timesteps (0 = none). Reduces noise for sporadic topics.
- `startDatetime` (string): Start datetime in GDELT format YYYYMMDDHHMMSS — exactly 14 digits, no separators (e.g. 20200101000000). Must pair with endDatetime; supplying only one of the two is rejected.
- `stations` (array): Station IDs to filter to (e.g. ["CNN", "FOXNEWS", "MSNBC"]). The GDELT TV API requires at least one station — supply it here, or embed a station: selector directly in query. Omitting both is rejected…
- `timespan` (string): Time window, e.g. "1m", "6m", "1y". Ignored when startDatetime/endDatetime are set. TV data spans 2009–October 2024.

Output parameters:

- `dateResolution` (string): Temporal resolution of data points.
- `effectiveQuery` (string): Echoed query string for use in follow-up calls.
- `normalized` (boolean): True when values are normalized coverage percentages.
- `notice` (string): Recovery hint when no TV coverage was found. Absent on successful responses.
- `series` (array): One series per station or combined national coverage.
- `timeRange` (object): Date range spanned by the returned data.
- `totalCount` (number): Number of station series returned.

### `gdelt_get_tv_clips` (~505 tokens)

Get GDELT TV Clips

Retrieve the top matching TV news clips (up to 3,000) for a query from the Internet Archive's Television News Archive. Each clip includes show name, station, air timestamp, a 15-second transcript excerpt, and a direct link to view the full one-minute clip. Use after gdelt_search_tv to read the actual transcript content driving a coverage spike. 3,000 is a hard per-call ceiling and GDELT offers no cursor: when a query fills it, split the run into narrower startDatetime/endDatetime windows — the response hands back the exact windows to use. Archive coverage spans 2009–October 2024.

Input parameters:

- `endDatetime` (string): End datetime in GDELT format YYYYMMDDHHMMSS — exactly 14 digits, no separators (e.g. 20200131235959). Must pair with startDatetime; supplying only one of the two is rejected.
- `maxRecords` (integer): Maximum number of clips to return (1–3000). 3000 is GDELT's hard per-call ceiling, not a page size — there is no cursor past it, so a query that fills 3000 must be split into narrower startDatetime/e…
- `query` (string, required): Search query for TV transcript content. Same TV operators as gdelt_search_tv: station:CNN, network:CBS, market:"National", show:"Anderson Cooper", context:"vaccine".
- `sort` (string): Sort order: relevance (default), dateDesc (newest first), dateAsc (oldest first).
- `startDatetime` (string): Start datetime in GDELT format YYYYMMDDHHMMSS — exactly 14 digits, no separators (e.g. 20200101000000). Must pair with endDatetime; supplying only one of the two is rejected.
- `stations` (array): Station IDs to filter to (e.g. ["CNN", "FOXNEWS"]). The GDELT TV API requires at least one station — supply it here, or embed a station: selector directly in query. Omitting both is rejected; it does…
- `timespan` (string): Time window, e.g. "1m", "6m". Ignored when startDatetime/endDatetime are set. TV data spans 2009–October 2024.

Output parameters:

- `clips` (array): Matching TV clips sorted per the sort parameter.
- `continuationWindows` (array): The queried window halved, to re-run this query against one pair at a time when maxRecords is at its 3000 ceiling. The halves overlap by one second so no clip falls through the seam; a clip aired on…
- `effectiveQuery` (string): Echoed query string for use in follow-up calls.
- `notice` (string): Disclosure that the maxRecords cap was reached and more clips may exist, naming the route to them — a higher maxRecords below the 3000 ceiling, or a narrower date window at it. Absent when the full r…
- `totalCount` (number): Number of clips returned.

### `gdelt_get_tv_context` (~382 tokens)

Get GDELT TV Context

Get the top co-occurring words and phrases from TV news clips matching a query — the vocabulary framing a topic on television. Returns the most frequent non-stopword terms from matching clips, with relative frequency scores (0–100, where 100 = the query term itself). Use to understand narrative framing, identify related concepts mentioned alongside a topic, or generate follow-up search terms. TV data spans 2009–October 2024.

Input parameters:

- `endDatetime` (string): End datetime in GDELT format YYYYMMDDHHMMSS — exactly 14 digits, no separators (e.g. 20200131235959). Must pair with startDatetime; supplying only one of the two is rejected.
- `query` (string, required): Search query for TV transcript content. Same TV operators as gdelt_search_tv: station:CNN, network:CBS, market:"National", show:"Anderson Cooper", context:"vaccine".
- `startDatetime` (string): Start datetime in GDELT format YYYYMMDDHHMMSS — exactly 14 digits, no separators (e.g. 20200101000000). Must pair with endDatetime; supplying only one of the two is rejected. TV data spans 2009–Octob…
- `stations` (array): Station IDs to filter to (e.g. ["CNN", "FOXNEWS"]). The GDELT TV API requires at least one station — supply it here, or embed a station: selector directly in query. Omitting both is rejected; it does…
- `timespan` (string): Time window, e.g. "1m", "6m". Ignored when startDatetime/endDatetime are set. TV data spans 2009–October 2024.

Output parameters:

- `effectiveQuery` (string): Echoed query string for use in follow-up calls.
- `notice` (string): Recovery hint when no context was found. Absent on successful responses.
- `totalCount` (number): Number of clips from which co-occurrences were computed. Absent when the upstream API does not return a clip count.
- `words` (array): Co-occurring terms sorted by score descending.

### `gdelt_get_tv_trending` (~83 tokens)

Get GDELT TV Trending

Retrieve trending topics, keywords, and phrases currently dominating US television news across national networks. No query required — returns the top memes of the present news cycle. Updated every 15 minutes. Note: the GDELT TV archive feed stopped updating around October 2024; results from this endpoint reflect that most-recent archived data rather than a live feed.

Output parameters:

- `notice` (string): Recovery hint when no trending topics were returned. Absent on successful responses.
- `topics` (array): Trending topics sorted by score descending.
- `totalCount` (number): Total number of trending topics returned.

### `gdelt_list_tv_stations` (~106 tokens)

List GDELT TV Stations

List all television stations available for TV search with their market, network, monitoring start date, and monitoring end date. Stations with an end date within the last 24 hours are flagged as active; stations with earlier end dates are discontinued. Use before querying to verify a station was active during the target time period, or to discover valid station IDs for the stations parameter in other TV tools. Most station monitoring ended October 2024 when the Internet Archive TV feed stopped updating.

Output parameters:

- `activeCount` (number): Number of stations currently flagged as active.
- `stations` (array): All TV stations sorted by station ID.
- `totalCount` (number): Total number of stations in the list.

## Diagnostics

Captured diagnostic sections: TLS, DNSSEC, Authorisation, Transports. The full working is on the page: https://verifymcp.io/servers/cyanheads-gdelt-mcp-server/gdelt#diagnostics

## Score history

- 2026-08-03: 67
- 2026-08-02: 67
- 2026-08-01: 66
- 2026-07-31: 66
- 2026-07-30: 64
- 2026-07-29: 64
- 2026-07-28: 63
- 2026-07-27: 62
- 2026-07-26: 62

## Links

- Remote endpoint: https://gdelt.caseyjhand.com/mcp
- Repository: https://github.com/cyanheads/gdelt-mcp-server
- Changelog RSS feed: https://verifymcp.io/servers/cyanheads-gdelt-mcp-server/gdelt/changelog.xml
- Changelog JSON feed: https://verifymcp.io/servers/cyanheads-gdelt-mcp-server/gdelt/changelog.json
- HTML version of this page: https://verifymcp.io/servers/cyanheads-gdelt-mcp-server/gdelt
