Skip to main content
Glama

Search GDELT Articles

gdelt_search_articles
Read-only

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 every fetched article inside the requested window. 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, 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.

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "query": "<query>"
    },
    "name": "gdelt_search_articles"
  }
}

Input Schema

NameRequiredDescriptionDefault
sortNoSort order: relevance (default), dateDesc/dateAsc, toneDesc/toneAsc, or hybridRel (GDELT hybrid relevance and recency).relevance
queryYesSearch 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".
timespanNoTime 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.
maxRecordsNoMaximum number of articles to fetch. Defaults to 75; values above 250 run at 250 with a limitClamp disclosure unless clamping is disabled. Every fetched in-window record is returned. 250 is GDELT's hard per-call ceiling, with no cursor; split a query that fills it into narrower startDatetime/endDatetime windows.
endDatetimeNoEnd 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.
startDatetimeNoStart 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.

Output Schema

NameRequiredDescriptionDefault
errorNoPresent when the call failed. Absent on success.
noticeNoGuidance on an incomplete or empty result. When no articles matched, how to broaden the query or window. When GDELT returned articles dated outside an explicit startDatetime/endDatetime window, how many were dropped. When the maxRecords cap was reached, raise maxRecords below the 250 ceiling or narrow the date window at it. When the server's local GKG mirror answered (source: gkg_mirror), why, and how its answer differs from the DOC API's. Absent when a non-empty result set from the DOC API is below the cap and no article was dropped as out of window.
sourceNoWhere this answer came from: doc_api, the GDELT DOC API, or gkg_mirror, the server's local mirror of GDELT's Global Knowledge Graph, which answers when the DOC API refuses the request or returns nothing. Present on every answer while the server runs a mirror; absent otherwise.
articlesNoMatching articles sorted per the sort parameter.
attemptsNoEach source tried for this call, in order. Present only when the DOC API did not answer with data and the mirror was consulted.
coverageNoPresent only when the mirror answered less than the requested window. Every count, share, and article in this response comes from answeredStart through answeredEnd; nothing outside it, or in a missing slot, was counted.
timespanNoEchoed timespan parameter when provided.
limitClampNoPresent only when the requested count exceeded the per-call cap: the call ran exactly as a call at the cap, and every count, notice, and continuation in this response reflects the applied value.
totalCountNoNumber of articles returned in this response.
staleResponseNoPresent only when the refetch of this exact request was refused, failed, or came back empty, and the response is GDELT's stored answer from fetchedAt instead. It holds nothing published after fetchedAt; a relative timespan covers the window ending at fetchedAt, not now. Absent on a live answer.
effectiveQueryNoEchoed query string for use in follow-up calls.
continuationWindowsNoWindows to re-run this query against when maxRecords reaches its 250 ceiling: the queried window halved, overlapping by one second so no article falls through the seam. De-duplicate by url. Absent when no window is known or narrowing cannot reach further articles.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed5 schema fields changed
    • addedOutput schema / properties / attempts
      Added value: +{
      +  "description": "Each source tried for this call, in order. Present only when the DOC API did not answer with data and the mirror was consulted.",
      +  "items": {
      +    "additionalProperties": false,
      +    "description": "One source's outcome for this call.",
      +    "properties": {
      +      "detail": {
      +        "description": "Why, when the outcome has a reason: DOC's failure message or the mirror's.",
      +        "type": "string"
      +      },
      +      "outcome": {
      +        "description": "What the source did: answered, empty (answered with no matches), rate_limited, or unavailable; or why the mirror could not answer: not_ready (no completed sync), not_compiled (the query or its timespan is in a form the mirror cannot evaluate), outside_coverage (the window lies outside the days it holds), store_error.",
      +        "enum": [
      +          "answered",
      +          "empty",
      +          "rate_limited",
      +          "unavailable",
      +          "not_ready",
      +          "not_compiled",
      +          "outside_coverage",
      +          "store_error"
      +        ],
      +        "type": "string"
      +      },
      +      "source": {
      +        "description": "The source tried.",
      +        "enum": [
      +          "doc_api",
      +          "gkg_mirror"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "source",
      +      "outcome"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / coverage
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "Present only when the mirror answered less than the requested window. Every count, share, and article in this response comes from answeredStart through answeredEnd; nothing outside it, or in a missing slot, was counted.",
      +  "properties": {
      +    "answeredEnd": {
      +      "description": "End of the window the mirror answered, ISO 8601 UTC.",
      +      "type": "string"
      +    },
      +    "answeredStart": {
      +      "description": "Start of the window the mirror answered, ISO 8601 UTC.",
      +      "type": "string"
      +    },
      +    "missingSlots": {
      +      "description": "15-minute GKG slots inside the answered window that the mirror holds no data for.",
      +      "type": "number"
      +    },
      +    "requestedEnd": {
      +      "description": "End of the requested window, ISO 8601 UTC.",
      +      "type": "string"
      +    },
      +    "requestedStart": {
      +      "description": "Start of the requested window, ISO 8601 UTC.",
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "requestedStart",
      +    "requestedEnd",
      +    "answeredStart",
      +    "answeredEnd",
      +    "missingSlots"
      +  ],
      +  "type": "object"
      +}
    • changedOutput schema / properties / notice / description
      Previous value: -"Guidance on an incomplete or empty result. When no articles matched, how to broaden the query or window. When GDELT returned articles dated outside an explicit startDatetime/endDatetime window, how many were dropped. When the maxRecords cap was reached, raise maxRecords below the 250 ceiling or narrow the date window at it. Absent when a non-empty result set is below the cap and no article was dropped as out of window."New value: +"Guidance on an incomplete or empty result. When no articles matched, how to broaden the query or window. When GDELT returned articles dated outside an explicit startDatetime/endDatetime window, how many were dropped. When the maxRecords cap was reached, raise maxRecords below the 250 ceiling or narrow the date window at it. When the server's local GKG mirror answered (source: gkg_mirror), why, and how its answer differs from the DOC API's. Absent when a non-empty result set from the DOC API is below the cap and no article was dropped as out of window."
    • addedOutput schema / properties / source
      Added value: +{
      +  "description": "Where this answer came from: doc_api, the GDELT DOC API, or gkg_mirror, the server's local mirror of GDELT's Global Knowledge Graph, which answers when the DOC API refuses the request or returns nothing. Present on every answer while the server runs a mirror; absent otherwise.",
      +  "enum": [
      +    "doc_api",
      +    "gkg_mirror"
      +  ],
      +  "type": "string"
      +}
    • addedOutput schema / properties / staleResponse
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "Present only when the refetch of this exact request was refused, failed, or came back empty, and the response is GDELT's stored answer from fetchedAt instead. It holds nothing published after fetchedAt; a relative timespan covers the window ending at fetchedAt, not now. Absent on a live answer.",
      +  "properties": {
      +    "ageSeconds": {
      +      "description": "Age of the stored answer when served, in whole seconds.",
      +      "type": "number"
      +    },
      +    "fetchedAt": {
      +      "description": "ISO 8601 time GDELT returned the stored answer.",
      +      "type": "string"
      +    },
      +    "reason": {
      +      "description": "Why the refetch was not used: GDELT rate-limited it, did not answer with data, or answered empty — which GDELT also does under load.",
      +      "enum": [
      +        "gdelt_rate_limited",
      +        "gdelt_unavailable",
      +        "gdelt_empty"
      +      ],
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "fetchedAt",
      +    "ageSeconds",
      +    "reason"
      +  ],
      +  "type": "object"
      +}
  2. Changed7 schema fields changed
    • changedInput schema / properties / maxRecords / description
      Previous value: -"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."New value: +"Maximum number of articles to fetch. Defaults to 75; values above 250 run at 250 with a limitClamp disclosure unless clamping is disabled. Every fetched in-window record is returned. 250 is GDELT's hard per-call ceiling, with no cursor; split a query that fills it into narrower startDatetime/endDatetime windows."
    • removedInput schema / properties / maxRecords / maximum
      Removed value: -2500
    • addedInput schema / properties / maxRecords / multipleOf
      Added value: +1
    • changedInput schema / properties / maxRecords / type
      Previous value: -"integer"New value: +"number"
    • changedOutput schema / properties / continuationWindows / description
      Previous value: -"Windows to re-run this query against, one at a time, when more articles are out of reach of this response. For a response cut to its budget under dateDesc or dateAsc: one window resuming from the last returned article, reaching back to the second it was published, so articles from that second come back again — or, when resuming there cannot reach a new article, one window skipping past that second. Otherwise — maxRecords at its 250 ceiling, or a cut under any other sort — the queried window halved, overlapping by one second so no article falls through the seam. Either way, de-duplicate by url. Absent when no window is known, or none would reach further."New value: +"Windows to re-run this query against when maxRecords reaches its 250 ceiling: the queried window halved, overlapping by one second so no article falls through the seam. De-duplicate by url. Absent when no window is known or narrowing cannot reach further articles."
    • changedOutput schema / properties / notice / description
      Previous value: -"Guidance on an incomplete or empty result. When no articles matched, how to broaden the query or window. When GDELT returned articles dated outside an explicit startDatetime/endDatetime window, how many were dropped. When the response was cut to its 48,000-byte budget, how many articles it withheld and the route to them. When the maxRecords cap was reached on an uncut response, that more articles may exist — a higher maxRecords below the 250 ceiling, or a narrower date window at it. Absent when a non-empty result set fit under both the cap and the budget and no article was dropped as out of window."New value: +"Guidance on an incomplete or empty result. When no articles matched, how to broaden the query or window. When GDELT returned articles dated outside an explicit startDatetime/endDatetime window, how many were dropped. When the maxRecords cap was reached, raise maxRecords below the 250 ceiling or narrow the date window at it. Absent when a non-empty result set is below the cap and no article was dropped as out of window."
    • removedOutput schema / properties / withheldCount
      Removed value: -{
      -  "description": "Articles GDELT returned inside the window that this response withheld to stay within its 48,000-byte budget — fetched minus returned, not counting articles dropped for falling outside an explicit window. Absent when every in-window article fit.",
      -  "type": "number"
      -}
  3. Changed4 schema fields changed
    • changedInput schema / properties / maxRecords / description
      Previous value: -"Maximum number of articles to fetch (1–250); 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."New value: +"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."
    • changedInput schema / properties / maxRecords / maximum
      Previous value: -250New value: +2500
    • addedOutput schema / properties / limitClamp
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "Present only when the requested count exceeded the per-call cap: the call ran exactly as a call at the cap, and every count, notice, and continuation in this response reflects the applied value.",
      +  "properties": {
      +    "applied": {
      +      "description": "The per-call cap the call ran with instead.",
      +      "type": "number"
      +    },
      +    "parameter": {
      +      "description": "The count input that was clamped.",
      +      "enum": [
      +        "maxRecords",
      +        "limit"
      +      ],
      +      "type": "string"
      +    },
      +    "requested": {
      +      "description": "The value the call asked for.",
      +      "type": "number"
      +    }
      +  },
      +  "required": [
      +    "parameter",
      +    "requested",
      +    "applied"
      +  ],
      +  "type": "object"
      +}
    • changedOutput schema / properties / notice / description
      Previous value: -"Guidance on an incomplete or empty result. When no articles matched, how to broaden the query or window. When GDELT returned articles dated outside an explicit startDatetime/endDatetime window, how many were dropped. When the response was cut to its 48,000-byte budget, how many articles it withheld and the route to them. When the maxRecords cap was reached on an uncut response, that more articles may exist — a higher maxRecords below the 250 ceiling, or a narrower date window at it. Absent when a non-empty result set fit under both the cap and the budget."New value: +"Guidance on an incomplete or empty result. When no articles matched, how to broaden the query or window. When GDELT returned articles dated outside an explicit startDatetime/endDatetime window, how many were dropped. When the response was cut to its 48,000-byte budget, how many articles it withheld and the route to them. When the maxRecords cap was reached on an uncut response, that more articles may exist — a higher maxRecords below the 250 ceiling, or a narrower date window at it. Absent when a non-empty result set fit under both the cap and the budget and no article was dropped as out of window."
  4. Changed1 schema field changed
    • changedInput schema / properties / query / description
      Previous value: -"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 virus\", repeat3:\"outbreak\"."New value: +"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\"."
  5. Changed6 schema fields changed
    • changedInput schema / properties / maxRecords / description
      Previous value: -"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/endDatetime windows instead."New value: +"Maximum number of articles to fetch (1–250); 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."
    • changedOutput schema / properties / continuationWindows / description
      Previous value: -"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 published on that second can come back in both, so de-duplicate by url. Absent unless the ceiling was reached with a window that is both known and wide enough to divide."New value: +"Windows to re-run this query against, one at a time, when more articles are out of reach of this response. For a response cut to its budget under dateDesc or dateAsc: one window resuming from the last returned article, reaching back to the second it was published, so articles from that second come back again — or, when resuming there cannot reach a new article, one window skipping past that second. Otherwise — maxRecords at its 250 ceiling, or a cut under any other sort — the queried window halved, overlapping by one second so no article falls through the seam. Either way, de-duplicate by url. Absent when no window is known, or none would reach further."
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `no_articles`: No articles matched the query within the specified time range. `invalid_date_range`: Only one of startDatetime / endDatetime was supplied, one of them is not a real UTC calendar timestamp, or startDatetime is not earlier than endDatetime. `invalid_query`: GDELT rejected the query string as malformed — bad keyword length, unbalanced parentheses, or an illegal character. `gdelt_rate_limited`: GDELT rejected the request for its one-request-per-five-seconds limit, or too many requests were already queued for this one to start in time. `gdelt_unavailable`: GDELT DOC API is unreachable or temporarily returned no usable data. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `invalid_date_range`: Only one of startDatetime / endDatetime was supplied, one of them is not a real UTC calendar timestamp, or startDatetime is not earlier than endDatetime. `invalid_query`: GDELT rejected the query string as malformed — bad keyword length, unbalanced parentheses, or an illegal character. `gdelt_rate_limited`: GDELT rejected the request for its one-request-per-five-seconds limit, or too many requests were already queued for this one to start in time. `gdelt_unavailable`: GDELT DOC API is unreachable or temporarily returned no usable data. Other values are possible when a failure originates below the handler."
    • changedOutput schema / properties / error / properties / data / properties / reason / examples
      Previous value: -[
      -  "no_articles",
      -  "invalid_date_range",
      -  "invalid_query",
      -  "gdelt_rate_limited",
      -  "gdelt_unavailable"
      -]New value: +[
      +  "invalid_date_range",
      +  "invalid_query",
      +  "gdelt_rate_limited",
      +  "gdelt_unavailable"
      +]
    • changedOutput schema / properties / notice / description
      Previous value: -"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 result set fit under the cap."New value: +"Guidance on an incomplete or empty result. When no articles matched, how to broaden the query or window. When GDELT returned articles dated outside an explicit startDatetime/endDatetime window, how many were dropped. When the response was cut to its 48,000-byte budget, how many articles it withheld and the route to them. When the maxRecords cap was reached on an uncut response, that more articles may exist — a higher maxRecords below the 250 ceiling, or a narrower date window at it. Absent when a non-empty result set fit under both the cap and the budget."
    • addedOutput schema / properties / withheldCount
      Added value: +{
      +  "description": "Articles GDELT returned inside the window that this response withheld to stay within its 48,000-byte budget — fetched minus returned, not counting articles dropped for falling outside an explicit window. Absent when every in-window article fit.",
      +  "type": "number"
      +}
  6. Changed1 schema field changed
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `no_articles`: No articles matched the query within the specified time range. `invalid_date_range`: Exactly one of startDatetime / endDatetime was supplied. `invalid_query`: GDELT rejected the query string as malformed — bad keyword length, unbalanced parentheses, or an illegal character. `gdelt_rate_limited`: GDELT rejected the request for its one-request-per-five-seconds limit, or too many requests were already queued for this one to start in time. `gdelt_unavailable`: GDELT DOC API is unreachable or temporarily returned no usable data. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `no_articles`: No articles matched the query within the specified time range. `invalid_date_range`: Only one of startDatetime / endDatetime was supplied, one of them is not a real UTC calendar timestamp, or startDatetime is not earlier than endDatetime. `invalid_query`: GDELT rejected the query string as malformed — bad keyword length, unbalanced parentheses, or an illegal character. `gdelt_rate_limited`: GDELT rejected the request for its one-request-per-five-seconds limit, or too many requests were already queued for this one to start in time. `gdelt_unavailable`: GDELT DOC API is unreachable or temporarily returned no usable data. Other values are possible when a failure originates below the handler."
  7. Changed1 schema field changed
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `no_articles`: No articles matched the query within the specified time range. `invalid_date_range`: Exactly one of startDatetime / endDatetime was supplied. `invalid_query`: GDELT rejected the query string as malformed — bad keyword length, unbalanced parentheses, or an illegal character. `gdelt_rate_limited`: GDELT rejected the request because its one-request-per-five-seconds limit was reached. `gdelt_unavailable`: GDELT DOC API is unreachable or temporarily returned no usable data. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `no_articles`: No articles matched the query within the specified time range. `invalid_date_range`: Exactly one of startDatetime / endDatetime was supplied. `invalid_query`: GDELT rejected the query string as malformed — bad keyword length, unbalanced parentheses, or an illegal character. `gdelt_rate_limited`: GDELT rejected the request for its one-request-per-five-seconds limit, or too many requests were already queued for this one to start in time. `gdelt_unavailable`: GDELT DOC API is unreachable or temporarily returned no usable data. Other values are possible when a failure originates below the handler."
  8. Changed2 schema fields changed
    • changedInput schema / properties / sort / description
      Previous value: -"Sort order: relevance (default), date (newest first), social (most socially shared)."New value: +"Sort order: relevance (default), dateDesc/dateAsc, toneDesc/toneAsc, or hybridRel (GDELT hybrid relevance and recency)."
    • changedInput schema / properties / sort / enum
      Previous value: -[
      -  "date",
      -  "relevance",
      -  "social"
      -]New value: +[
      +  "relevance",
      +  "dateDesc",
      +  "dateAsc",
      +  "toneDesc",
      +  "toneAsc",
      +  "hybridRel"
      +]
  9. Changed3 schema fields changed
    • changedInput schema / properties / timespan / description
      Previous value: -"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."New value: +"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."
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `no_articles`: No articles matched the query within the specified time range. `invalid_date_range`: Exactly one of startDatetime / endDatetime was supplied. `invalid_query`: GDELT rejected the query string as malformed — bad keyword length, unbalanced parentheses, or an illegal character. `gdelt_unavailable`: GDELT DOC API is unreachable or rate-limited. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `no_articles`: No articles matched the query within the specified time range. `invalid_date_range`: Exactly one of startDatetime / endDatetime was supplied. `invalid_query`: GDELT rejected the query string as malformed — bad keyword length, unbalanced parentheses, or an illegal character. `gdelt_rate_limited`: GDELT rejected the request because its one-request-per-five-seconds limit was reached. `gdelt_unavailable`: GDELT DOC API is unreachable or temporarily returned no usable data. Other values are possible when a failure originates below the handler."
    • changedOutput schema / properties / error / properties / data / properties / reason / examples
      Previous value: -[
      -  "no_articles",
      -  "invalid_date_range",
      -  "invalid_query",
      -  "gdelt_unavailable"
      -]New value: +[
      +  "no_articles",
      +  "invalid_date_range",
      +  "invalid_query",
      +  "gdelt_rate_limited",
      +  "gdelt_unavailable"
      +]
  10. Changed6 schema fields changed
    • changedInput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • addedInput schema / additionalProperties
      Added value: +false
    • changedOutput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • addedOutput schema / anyOf
      Added value: +[
      +  {
      +    "not": {
      +      "required": [
      +        "error"
      +      ]
      +    },
      +    "required": [
      +      "articles",
      +      "effectiveQuery",
      +      "totalCount"
      +    ]
      +  },
      +  {
      +    "required": [
      +      "error"
      +    ]
      +  }
      +]
    • addedOutput schema / properties / error
      Added value: +{
      +  "additionalProperties": {},
      +  "description": "Present when the call failed. Absent on success.",
      +  "properties": {
      +    "code": {
      +      "description": "JSON-RPC error code for this failure.",
      +      "maximum": 9007199254740991,
      +      "minimum": -9007199254740991,
      +      "type": "integer"
      +    },
      +    "data": {
      +      "additionalProperties": {},
      +      "properties": {
      +        "reason": {
      +          "description": "Machine-readable failure mode. Declared by this tool: `no_articles`: No articles matched the query within the specified time range. `invalid_date_range`: Exactly one of startDatetime / endDatetime was supplied. `invalid_query`: GDELT rejected the query string as malformed — bad keyword length, unbalanced parentheses, or an illegal character. `gdelt_unavailable`: GDELT DOC API is unreachable or rate-limited. Other values are possible when a failure originates below the handler.",
      +          "examples": [
      +            "no_articles",
      +            "invalid_date_range",
      +            "invalid_query",
      +            "gdelt_unavailable"
      +          ],
      +          "type": "string"
      +        },
      +        "recovery": {
      +          "additionalProperties": {},
      +          "description": "Actionable next step for the caller.",
      +          "properties": {
      +            "hint": {
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "hint"
      +          ],
      +          "type": "object"
      +        },
      +        "retryable": {
      +          "description": "Whether retrying may succeed.",
      +          "type": "boolean"
      +        }
      +      },
      +      "type": "object"
      +    },
      +    "message": {
      +      "description": "Human-readable description of what went wrong.",
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "code",
      +    "message"
      +  ],
      +  "type": "object"
      +}
    • removedOutput schema / required
      Removed value: -[
      -  "articles",
      -  "effectiveQuery",
      -  "totalCount"
      -]
  11. Changed3 schema fields changed
    • changedInput schema / properties / maxRecords / description
      Previous value: -"Maximum number of articles to return (1–250)."New value: +"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/endDatetime windows instead."
    • addedOutput schema / properties / continuationWindows
      Added value: +{
      +  "description": "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 published on that second can come back in both, so de-duplicate by url. Absent unless the ceiling was reached with a window that is both known and wide enough to divide.",
      +  "items": {
      +    "additionalProperties": false,
      +    "description": "One window to re-query with the same query string.",
      +    "properties": {
      +      "endDatetime": {
      +        "description": "End of this window in GDELT format YYYYMMDDHHMMSS.",
      +        "type": "string"
      +      },
      +      "startDatetime": {
      +        "description": "Start of this window in GDELT format YYYYMMDDHHMMSS.",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "startDatetime",
      +      "endDatetime"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • changedOutput schema / properties / notice / description
      Previous value: -"Recovery hint when no articles matched — echoes filters and suggests how to broaden. Absent on successful responses."New value: +"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 result set fit under the cap."
  12. Changed4 schema fields changed
    • changedInput schema / properties / endDatetime / description
      Previous value: -"End of date range in GDELT format YYYYMMDDHHMMSS (e.g. 20240131235959). Must be used together with startDatetime."New value: +"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."
    • addedInput schema / properties / endDatetime / pattern
      Added value: +"^\\d{14}$"
    • changedInput schema / properties / startDatetime / description
      Previous value: -"Start of date range in GDELT format YYYYMMDDHHMMSS (e.g. 20240101000000). Must be used together with endDatetime."New value: +"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."
    • addedInput schema / properties / startDatetime / pattern
      Added value: +"^\\d{14}$"
  13. Changed5 schema fields changed
    • addedOutput schema / properties / effectiveQuery
      Added value: +{
      +  "description": "Echoed query string for use in follow-up calls.",
      +  "type": "string"
      +}
    • removedOutput schema / properties / query
      Removed value: -{
      -  "description": "Echoed query string for use in follow-up calls.",
      -  "type": "string"
      -}
    • addedOutput schema / properties / totalCount
      Added value: +{
      +  "description": "Number of articles returned in this response.",
      +  "type": "number"
      +}
    • removedOutput schema / properties / totalReturned
      Removed value: -{
      -  "description": "Number of articles returned in this response.",
      -  "type": "number"
      -}
    • changedOutput schema / required
      Previous value: -[
      -  "articles",
      -  "totalReturned",
      -  "query"
      -]New value: +[
      +  "articles",
      +  "effectiveQuery",
      +  "totalCount"
      +]
  14. First observed

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnlyHint, openWorldHint), yet the description adds substantial behavior: a hard 250 per-call ceiling with no cursor, every fetched in-window record is returned, limitClamp disclosure above 250, and startDatetime/endDatetime exclusivity. These are the operational traits an agent actually needs to plan calls.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose and window constraint are front-loaded and the paragraph is dense rather than padded. However the 250 hard ceiling / no-cursor constraint is stated twice (mid-paragraph and again as a note), and the query-operator list duplicates the query and theme parameter descriptions verbatim.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present the description needn't describe return records, and annotations cover the safety profile; what remains, the temporal coverage limit, the ceiling with no pagination, and the window-splitting recovery path, is all supplied. Nothing required to call this correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the schema already documents sort, timespan, maxRecords, the datetime patterns and the paired startDatetime/endDatetime rule, so the heavy lifting is done structurally. The description largely restates the same operators and the same 250/limitClamp behavior rather than adding syntax or edge-case meaning beyond them – baseline 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opening sentence gives a specific verb (Search), a bounded resource (last 3 months of global news, 65+ languages) and names the underlying API, and it explicitly separates itself from gdelt_search_tv (historical TV) and gdelt_search_themes (theme identifiers). An agent can route to this tool without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states when-not (only the most recent 3 months; use gdelt_search_tv for pre-2009 historical transcripts), points at gdelt_search_themes for valid theme identifiers, and gives an actionable recovery procedure when the 250-record ceiling is hit (re-query narrower startDatetime/endDatetime windows, response returns those windows). Alternatives and exclusions are both explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.