gdelt-mcp-server

v0.7.0 pre-1.0

Search and analyze global news coverage and US television transcripts from the GDELT Project's real-time APIs via MCP. STDIO or Streamable HTTP.

gdelt.caseyjhand.com/mcp
claude mcp add --transport http gdelt-mcp-server https://gdelt.caseyjhand.com/mcp
codex mcp add gdelt-mcp-server --url https://gdelt.caseyjhand.com/mcp
{
  "mcpServers": {
    "gdelt-mcp-server": {
      "url": "https://gdelt.caseyjhand.com/mcp"
    }
  }
}
gemini mcp add --transport http gdelt-mcp-server https://gdelt.caseyjhand.com/mcp
{
  "mcpServers": {
    "gdelt-mcp-server": {
      "command": "bunx",
      "args": [
        "mcp-remote",
        "https://gdelt.caseyjhand.com/mcp"
      ]
    }
  }
}
{
  "mcpServers": {
    "gdelt-mcp-server": {
      "type": "http",
      "url": "https://gdelt.caseyjhand.com/mcp"
    }
  }
}
curl -X POST https://gdelt.caseyjhand.com/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"curl","version":"1.0.0"}}}'

Tools

9

gdelt_search_articles

open-world

Search the last 3 months of global news coverage (65+ languages) using the GDELT DOC API. Fetches up to 250 articles with URL, title, source domain, language, country, publication date, and social image URL, and returns as many as fit a 48,000-byte response — the rest are counted in withheldCount, with a continuation to reach them. 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:TAX_DISEASE_OUTBREAK — find identifiers with gdelt_search_themes), 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 or a response comes back cut, re-query 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.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "gdelt_search_articles",
    "arguments": {
      "query": "<query>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "query": {
      "type": "string",
      "minLength": 1,
      "description": "Search query. Supports GDELT operators: phrases (\"bird flu\"), boolean OR ((flu OR pandemic)), sourcecountry:china, sourcelang:spanish, domain:who.int, theme:TAX_DISEASE_OUTBREAK (GKG theme identifiers come from gdelt_search_themes), tone<-5, near20:\"flu virus\", repeat3:\"outbreak\"."
    },
    "timespan": {
      "description": "Time window relative to now, minimum \"15min\"; other examples: \"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.",
      "type": "string"
    },
    "startDatetime": {
      "description": "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.",
      "type": "string",
      "pattern": "^\\d{14}$"
    },
    "endDatetime": {
      "description": "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.",
      "type": "string",
      "pattern": "^\\d{14}$"
    },
    "maxRecords": {
      "default": 75,
      "description": "Maximum number of articles to fetch (1–250; a value up to 2500 runs at 250, and the response says so in limitClamp). The response carries as many of them as fit its 48,000-byte budget. 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/endDatetime windows instead.",
      "type": "integer",
      "minimum": 1,
      "maximum": 2500
    },
    "sort": {
      "default": "relevance",
      "description": "Sort order: relevance (default), dateDesc/dateAsc, toneDesc/toneAsc, or hybridRel (GDELT hybrid relevance and recency).",
      "type": "string",
      "enum": [
        "relevance",
        "dateDesc",
        "dateAsc",
        "toneDesc",
        "toneAsc",
        "hybridRel"
      ]
    }
  },
  "required": [
    "query",
    "maxRecords",
    "sort"
  ],
  "additionalProperties": false
}
view source ↗

gdelt_get_coverage_timeline

open-world

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 inferred from returned intervals: 15 minutes or hours for short windows, days for longer ones. In volume_with_articles mode each timestep carries its first 3 article links and referenceCount, its true article count; name timesteps' dates in points to get only those timesteps, each with its full list. A response carries as many whole timesteps as fit its size budget; when more remain it returns nextOffset — pass it back as offset with otherwise identical inputs for the next page. Note: DOC API covers only the last 3 months.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "gdelt_get_coverage_timeline",
    "arguments": {
      "query": "<query>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "query": {
      "type": "string",
      "minLength": 1,
      "description": "Search query using GDELT syntax. Same operators as gdelt_search_articles: phrases, boolean OR, sourcecountry:, sourcelang:, domain:, theme: (GKG theme identifiers come from gdelt_search_themes), tone<."
    },
    "mode": {
      "default": "volume",
      "description": "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 score per timestep.",
      "type": "string",
      "enum": [
        "volume",
        "volume_with_articles",
        "tone"
      ]
    },
    "timespan": {
      "description": "Time window relative to now, minimum \"15min\"; other examples: \"24h\", \"7d\", \"1m\". Ignored when startDatetime/endDatetime are set. Maximum 3 months.",
      "type": "string"
    },
    "startDatetime": {
      "description": "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.",
      "type": "string",
      "pattern": "^\\d{14}$"
    },
    "endDatetime": {
      "description": "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.",
      "type": "string",
      "pattern": "^\\d{14}$"
    },
    "smoothing": {
      "description": "Smoothing window in timesteps (0 = none, 1–5 = moving average width). Reduces noise for spotty topics.",
      "type": "integer",
      "minimum": 0,
      "maximum": 5
    },
    "points": {
      "description": "Timestep dates to return alone, e.g. [\"2024-01-05T12:00:00Z\"]. Take them verbatim from series[].data[].date in a prior response, or from the list an unknown_point error prints. The response then carries only these timesteps, in timeline order, and in volume_with_articles mode each carries its complete article list instead of the first 3. A date matching no timestep is rejected rather than silently ignored.",
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "offset": {
      "default": 0,
      "description": "Zero-based timestep offset — into the timeline, or into the timesteps named in points. Pass nextOffset from the preceding response, with otherwise identical inputs, to get the next page.",
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "query",
    "mode",
    "offset"
  ],
  "additionalProperties": false
}
view source ↗

gdelt_get_tone_distribution

open-world

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 carries its first 3 representative article links and referenceCount, how many GDELT returned; name bins in the bins input to get only those bins, each with every link. A response carries as many whole bins as fit its size budget; when more remain it returns nextOffset — pass it back as offset with otherwise identical inputs for the next page. 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.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "gdelt_get_tone_distribution",
    "arguments": {
      "query": "<query>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "query": {
      "type": "string",
      "minLength": 1,
      "description": "Search query using GDELT syntax. Same operators as gdelt_search_articles: phrases, boolean OR, sourcecountry:, sourcelang:, domain:, theme: (GKG theme identifiers come from gdelt_search_themes)."
    },
    "timespan": {
      "description": "Time window relative to now, minimum \"15min\"; other examples: \"24h\", \"7d\", \"1m\". Ignored when startDatetime/endDatetime are set. Maximum 3 months.",
      "type": "string"
    },
    "startDatetime": {
      "description": "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.",
      "type": "string",
      "pattern": "^\\d{14}$"
    },
    "endDatetime": {
      "description": "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.",
      "type": "string",
      "pattern": "^\\d{14}$"
    },
    "bins": {
      "description": "Tone bins to return alone, e.g. [-7, 4]. Take them from histogram[].bin in a prior response, or from the list an unknown_bin error prints. The response then carries only these bins, in histogram order, each with every representative article link instead of the first 3. A value matching no bin is rejected rather than silently ignored.",
      "type": "array",
      "items": {
        "type": "integer",
        "minimum": -9007199254740991,
        "maximum": 9007199254740991
      }
    },
    "offset": {
      "default": 0,
      "description": "Zero-based bin offset — into the histogram, or into the bins named in bins. Pass nextOffset from the preceding response, with otherwise identical inputs, to get the next page.",
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "query",
    "offset"
  ],
  "additionalProperties": false
}
view source ↗

gdelt_get_coverage_breakdown

open-world

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 the top 10 series ranked by the sum of their values and names every other series under otherSeriesLabels — pass any labels, ranked or not, as the series input to get only those series, complete. A response carries as many whole series as fit its size budget; when more remain it returns nextOffset — pass it back as offset with otherwise identical inputs for the next page. Values are normalized: each point is the topic's share of that source's media output, not an absolute article count, so values from different sources do not add up to a share. 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.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "gdelt_get_coverage_breakdown",
    "arguments": {
      "query": "<query>",
      "breakdownBy": "<breakdownBy>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "query": {
      "type": "string",
      "minLength": 1,
      "description": "Search query using GDELT syntax. Same operators as gdelt_search_articles: phrases, boolean OR, sourcecountry:, sourcelang:, domain:, theme: (GKG theme identifiers come from gdelt_search_themes)."
    },
    "breakdownBy": {
      "type": "string",
      "enum": [
        "language",
        "country"
      ],
      "description": "Breakdown dimension: \"language\" for source language time series, \"country\" for source country time series."
    },
    "timespan": {
      "description": "Time window relative to now, minimum \"15min\"; other examples: \"24h\", \"7d\", \"1m\". Ignored when startDatetime/endDatetime are set. Maximum 3 months.",
      "type": "string"
    },
    "startDatetime": {
      "description": "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.",
      "type": "string",
      "pattern": "^\\d{14}$"
    },
    "endDatetime": {
      "description": "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.",
      "type": "string",
      "pattern": "^\\d{14}$"
    },
    "series": {
      "description": "Exact series labels to return instead of the ranked overview, e.g. [\"Portuguese\", \"Vietnamese\"]. Take them verbatim from otherSeriesLabels or topSeries[].label in a response, or from the label list an unknown_series error prints. Each one comes back complete under selectedSeries, in the order requested; a label that matches nothing is rejected rather than silently skipped. Omit to get the ranked overview.",
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "offset": {
      "default": 0,
      "description": "Zero-based series offset — into the ranked top 10, or into the series named in series. Pass nextOffset from the preceding response, with otherwise identical inputs, to get the next page.",
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "query",
    "breakdownBy",
    "offset"
  ],
  "additionalProperties": false
}
view source ↗

gdelt_search_themes

open-world

Find GDELT Global Knowledge Graph (GKG) theme identifiers for the theme: operator that gdelt_search_articles, gdelt_get_coverage_timeline, gdelt_get_tone_distribution, and gdelt_get_coverage_breakdown accept in query. Searches the identifiers in the GDELT GKG theme lookup, which carries no labels or descriptions: every query word must begin one of the _-separated parts of an identifier or run across consecutive parts, or all the words joined must, so "drought" finds NATURAL_DISASTER_DROUGHT, "cyberattack" finds CYBER_ATTACK, "plant disease" finds TAX_PLANTDISEASE, and "wb water" narrows to World Bank water themes. There is no stemming or synonym matching — "displacement" does not reach DISPLACED — except one fallback: when nothing matches, the search retries once with a trailing s dropped from each word of four or more letters, and says so. Matches rank an exact identifier first, then by the count the lookup lists — a static prevalence figure, not a live article total — and each carries a paste-ready operator such as theme:TAX_DISEASE_OUTBREAK. Page with offset and limit (up to 100 matches per page; a larger limit runs at 100).

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "gdelt_search_themes",
    "arguments": {
      "query": "<query>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "query": {
      "type": "string",
      "description": "Words to find in theme identifiers (e.g. \"drought\", \"cyber attack\", \"refugee\"), a family prefix with a word (\"wb water\", \"crisislex\"), or a whole identifier to confirm it is listed (\"TAX_DISEASE_OUTBREAK\"). Case-insensitive; a leading theme: is ignored; every word must match, or all the words joined must (\"plant disease\" matches TAX_PLANTDISEASE). Must contain at least one letter or digit."
    },
    "offset": {
      "default": 0,
      "description": "Zero-based offset into the ranked matches. Use nextOffset from the preceding response with the same query to retrieve the next page.",
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    },
    "limit": {
      "default": 25,
      "description": "Maximum matches returned in this response (1–100; a value up to 1000 runs at 100, and the response says so in limitClamp).",
      "type": "integer",
      "minimum": 1,
      "maximum": 1000
    }
  },
  "required": [
    "query",
    "offset",
    "limit"
  ],
  "additionalProperties": false
}
view source ↗

gdelt_search_tv

open-world

Search US television news closed captions (2009–October 2024, 150+ stations) for spoken mentions of a query. Returns a bounded, paged per-station time series showing airtime devoted to the topic — up to 500 points per page; a larger limit runs at 500. Each series carries GDELT's display name for the station and, when that name resolves to one, the station ID gdelt_get_tv_clips takes as stations. 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.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "gdelt_search_tv",
    "arguments": {
      "query": "<query>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "query": {
      "type": "string",
      "minLength": 1,
      "description": "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."
    },
    "stations": {
      "description": "Up to 10 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; it does not fall back to all stations. Use gdelt_list_tv_stations to see valid station IDs.",
      "maxItems": 10,
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "timespan": {
      "description": "Time window, e.g. \"1m\", \"6m\", \"1y\". Ignored when startDatetime/endDatetime are set. TV data spans 2009–October 2024.",
      "type": "string"
    },
    "startDatetime": {
      "description": "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.",
      "type": "string",
      "pattern": "^\\d{14}$"
    },
    "endDatetime": {
      "description": "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.",
      "type": "string",
      "pattern": "^\\d{14}$"
    },
    "smoothing": {
      "description": "Smoothing window in timesteps (0 = none). Reduces noise for sporadic topics.",
      "type": "integer",
      "minimum": 0,
      "maximum": 5
    },
    "normalize": {
      "default": true,
      "description": "When true (default), values are normalized as % of total airtime, enabling cross-station comparison. When false, returns raw matching 15-second clip counts.",
      "type": "boolean"
    },
    "dateres": {
      "description": "Optional GDELT aggregation resolution. Omit to let GDELT choose from the query window; the effective recognized or inferred resolution is returned as dateResolution.",
      "type": "string",
      "enum": [
        "hour",
        "day",
        "week",
        "month",
        "year"
      ]
    },
    "offset": {
      "default": 0,
      "description": "Zero-based point offset into the deterministic date-then-station-name ordering. Use nextOffset from the preceding response with the same query inputs to retrieve the next page.",
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    },
    "limit": {
      "default": 500,
      "description": "Maximum timeline points returned in this response (1–500; a value up to 5000 runs at 500, and the response says so in limitClamp).",
      "type": "integer",
      "minimum": 1,
      "maximum": 5000
    }
  },
  "required": [
    "query",
    "normalize",
    "offset",
    "limit"
  ],
  "additionalProperties": false
}
view source ↗

gdelt_get_tv_clips

open-world

Retrieve the top matching TV news clips for a query from the Internet Archive's Television News Archive: fetches up to 3,000 and returns as many as fit a 48,000-byte response — the rest are counted in withheldCount, with a continuation to reach them. Each clip includes show name, the station's display name — with its station ID when that name resolves to one — 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 — pass a series' station value as stations here. GDELT answers TV windows in whole clock hours; clips it returns from outside an explicit startDatetime/endDatetime window are dropped, and continuing a cut response at maxRecords 3000 leaves room for them. 3,000 is a hard per-call ceiling and GDELT offers no cursor: when a query fills it or a response comes back cut, re-query narrower startDatetime/endDatetime windows — the response hands back the exact windows to use. Archive coverage spans 2009–October 2024.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "gdelt_get_tv_clips",
    "arguments": {
      "query": "<query>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "query": {
      "type": "string",
      "minLength": 1,
      "description": "Search query for TV transcript content. Same TV operators as gdelt_search_tv: station:CNN, network:CBS, market:\"National\", show:\"Anderson Cooper\", context:\"vaccine\"."
    },
    "stations": {
      "description": "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 not fall back to all stations. Use gdelt_list_tv_stations to see valid IDs.",
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "timespan": {
      "description": "Time window, e.g. \"1m\", \"6m\". Ignored when startDatetime/endDatetime are set. TV data spans 2009–October 2024.",
      "type": "string"
    },
    "startDatetime": {
      "description": "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.",
      "type": "string",
      "pattern": "^\\d{14}$"
    },
    "endDatetime": {
      "description": "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.",
      "type": "string",
      "pattern": "^\\d{14}$"
    },
    "maxRecords": {
      "default": 50,
      "description": "Maximum number of clips to fetch (1–3000; a value up to 30000 runs at 3000, and the response says so in limitClamp). The response carries as many of them as fit its 48,000-byte budget. 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/endDatetime windows instead.",
      "type": "integer",
      "minimum": 1,
      "maximum": 30000
    },
    "sort": {
      "default": "relevance",
      "description": "Sort order: relevance (default), dateDesc (newest first), dateAsc (oldest first).",
      "type": "string",
      "enum": [
        "relevance",
        "dateDesc",
        "dateAsc"
      ]
    }
  },
  "required": [
    "query",
    "maxRecords",
    "sort"
  ],
  "additionalProperties": false
}
view source ↗

gdelt_get_tv_context

open-world

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 with relative frequency scores (0–100, where 100 = the query term itself). Terms and scores come from GDELT's relevance-ranked sample of matching clips, documented as the 200 most relevant, not all matching coverage — compare windows or stations with a separate, narrower call for each. Use to understand narrative framing, identify related concepts mentioned alongside a topic, or generate follow-up search terms. TV data spans 2009–October 2024.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "gdelt_get_tv_context",
    "arguments": {
      "query": "<query>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "query": {
      "type": "string",
      "minLength": 1,
      "description": "Search query for TV transcript content. Same TV operators as gdelt_search_tv: station:CNN, network:CBS, market:\"National\", show:\"Anderson Cooper\", context:\"vaccine\"."
    },
    "stations": {
      "description": "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 not fall back to all stations. Use gdelt_list_tv_stations to see valid IDs.",
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "timespan": {
      "description": "Time window, e.g. \"1m\", \"6m\". Ignored when startDatetime/endDatetime are set. TV data spans 2009–October 2024.",
      "type": "string"
    },
    "startDatetime": {
      "description": "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–October 2024.",
      "type": "string",
      "pattern": "^\\d{14}$"
    },
    "endDatetime": {
      "description": "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.",
      "type": "string",
      "pattern": "^\\d{14}$"
    }
  },
  "required": [
    "query"
  ],
  "additionalProperties": false
}
view source ↗

gdelt_list_tv_stations

open-world

List the television stations available for TV search with their market, network, monitoring start date, and monitoring end date — every station by default, or only those matching the optional stations, network, and market filters (each an exact, case-insensitive match; combined with AND). activeCount and totalCount count the returned stations. 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.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "gdelt_list_tv_stations",
    "arguments": {}
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "stations": {
      "description": "Station IDs to return (e.g. [\"CNN\", \"FOXNEWS\", \"MSNBC\"]) — the IDs the stations parameter of the other TV tools takes. Matches any listed ID, exactly and case-insensitively after trimming; IDs that match no station are named in the notice. Blank entries are ignored; omit it or pass [] to include every station.",
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "network": {
      "description": "Network to narrow to (e.g. \"CNN\", \"ABC\"), matched as a whole value case-insensitively after trimming — \"FOX\" does not match \"FOXNEWS\". Values come from the network field of the unfiltered list. Blank is ignored.",
      "type": "string"
    },
    "market": {
      "description": "Market to narrow to (e.g. \"National\", \"San Francisco\"), matched as a whole value case-insensitively after trimming — \"National\" does not match \"NationalSpecialty\". Values come from the market field of the unfiltered list. Blank is ignored.",
      "type": "string"
    }
  },
  "additionalProperties": false
}
view source ↗