nz-news
Aggregate RSS feeds from major New Zealand news websites. Use when the task involves NZ news, current events in New Zealand, what's happening in NZ, NZ headlines, or searching NZ stories by topic, tim
SKILL.mdskills/nz-news/SKILL.md
GitHubNZ News
Goal
Aggregate live RSS feeds from major New Zealand news websites into a single CLI tool for quick headline scanning, source browsing, and obvious topic searching.
Use this when
- A user asks about current NZ news or what's happening in New Zealand
- A user wants today's headlines from NZ media
- A user asks about news from a specific NZ outlet (Stuff, RNZ, NZ Herald, etc.)
- A user wants to search NZ news by topic, keyword, timeframe, or source
- A user needs a quick New Zealand news briefing
Do not use this for
- International news not covered by NZ outlets
- Historical news or archived articles
- Paywalled content (some NZ Herald articles may be paywalled)
- Social media or non-news content
- Real-time breaking news alerts (RSS feeds have a delay)
Preferred workflow
- Run
scripts/cli.pywith the narrowest subcommand that answers the task - Start with
searchfor any topic lookup, either positionally or with flags - Use
--source,--since-hours,--since-date,--contains-all,--exact, and--excludewhen the request needs tighter matching - Terms match whole words by default; add
--substringonly when parts of words must match - Use default human output for direct answers
- Use
--jsonwhen another tool or agent needs machine-readable output
CLI
Run with:
python3 skills/nz-news/scripts/cli.py <command> [flags]
Search first
The easiest path for topic lookups is now search.
Examples:
python3 skills/nz-news/scripts/cli.py search cyclone
python3 skills/nz-news/scripts/cli.py search --keyword cyclone --since-hours 24
python3 skills/nz-news/scripts/cli.py search --keyword "housing market" --contains-all --source rnz,newsroom
python3 skills/nz-news/scripts/cli.py search --keyword coalition --exact --since-date 2026-04-01
python3 skills/nz-news/scripts/cli.py topic cyclone --exclude sport --limit 5
topic is kept as an alias for search, so both of these work:
python3 skills/nz-news/scripts/cli.py topic cyclone
python3 skills/nz-news/scripts/cli.py search --keyword cyclone
headlines [--limit N] [--json]
Top headlines across all primary sources (NZ Herald, Stuff, RNZ, Newsroom, The Spinoff, Interest.co.nz), deduplicated and sorted by date. Default limit: 10.
Examples:
python3 skills/nz-news/scripts/cli.py headlines
python3 skills/nz-news/scripts/cli.py headlines --limit 20
python3 skills/nz-news/scripts/cli.py headlines --json
source <name> [--limit N] [--json]
News from a specific source. Accepts source ID (for example rnz, stuff, herald) or a source name. Default limit: 10.
Examples:
python3 skills/nz-news/scripts/cli.py source rnz
python3 skills/nz-news/scripts/cli.py source stuff --limit 5
python3 skills/nz-news/scripts/cli.py source herald --json
search [keyword...] [flags]
Search headlines and summaries across NZ sources. You can provide the search term positionally or with --keyword.
Useful flags:
--keyword <text>for flag-based search input--source rnz,heraldto limit the search to specific feeds--since-hours <hours>to keep only recent stories--since-date <YYYY-MM-DD or ISO timestamp>for a fixed start date--contains-allto require every term in a multi-word query--exactto match an exact phrase--exclude sport,opinionto remove unwanted terms--substringto use the old matching, where a term can match inside a longer word--limit N--json
Matching rules:
- Matching is case-insensitive and uses whole words.
AImatches "AI", "AI-driven", "AI's" and "A.I.". It does not match "against" or "said". - A multi-word query matches as a phrase of whole words.
housing marketmatches "housing-market" but not "rehousing marketplace". --contains-allneeds each word, in any order.--exactneeds the full phrase.--excluderemoves a story if it has the full excluded term as whole words; each excluded word also covers its simple plural (sportdrops "sports" but not "transport").- Hyphens, apostrophes and other punctuation separate words, so
co-opmatches "co-op" and "co op". Macrons and other accents fold, soMāorimatches "Māori" and "Maori". --substringcannot be used with--exact.
JSON shape:
fetchedAtkeywordmatchMode:phrase(default),contains-all,exact, orsubstring(--substringonly)wordMatch:trueunless--substringis setsourcesQueriedsourcesOkfilters.sourceIdsfilters.sinceHoursfilters.sinceDatefilters.excludefilters.limittotalMatchingreturnedCountitems[]withtitle,url,published,source,sourceId,summaryerrors[]
Examples:
python3 skills/nz-news/scripts/cli.py search cyclone
python3 skills/nz-news/scripts/cli.py search --keyword cyclone --since-hours 24
python3 skills/nz-news/scripts/cli.py search --keyword "housing market" --contains-all --source rnz,newsroom
python3 skills/nz-news/scripts/cli.py search --keyword coalition --exact --since-date 2026-04-01
python3 skills/nz-news/scripts/cli.py topic cyclone --exclude sport --limit 5 --json
sources [--json]
List all available news sources with a live status check showing which feeds are working, how many items each returned, and response time.
Examples:
python3 skills/nz-news/scripts/cli.py sources
python3 skills/nz-news/scripts/cli.py sources --json
summary [--json]
Brief summary showing total story count across sources and the top 5 headlines.
Examples:
python3 skills/nz-news/scripts/cli.py summary
python3 skills/nz-news/scripts/cli.py summary --json
interviews --programme NAME [--contains TEXT] [--limit N] [--json]
Discover interview candidates in the last90days from one programme feed. The
window is exactly the previous 90 days through the current UTC instant; future
and undated episodes are excluded. mike-hosking is live-tested.
rnz-morning-report currently reports a robots block without fetching its feed.
python3 skills/nz-news/scripts/cli.py interviews --programme mike-hosking --limit 5 --json
python3 skills/nz-news/scripts/cli.py interviews --programme mike-hosking --contains Minister --json
python3 skills/nz-news/scripts/cli.py interviews --programme rnz-morning-report --json
Results contain source URL, programme, source-title speaker attribution, publication date, unknown broadcast date, advertised transcript links, and exact feed/GUID/date-field provenance. Speaker attribution is explicitly unverified; this does not establish an utterance, identity, office history or party alignment. No political persuasion, voter profiling, audio or transcript downloads.
The feed read is capped at 512 KiB. Only complete items in that prefix count.
coverage.window_complete is false: this is discovery within a rolling window,
not a complete 90-day archive. A no-match result is scoped to the scanned prefix.
The JSON result envelope distinguishes empty, blocked, unavailable and
schema_error. See interview API notes.
Sources
| ID | Name | Format | Type |
|---|---|---|---|
| herald | NZ Herald | RSS | Primary |
| stuff | Stuff | Atom | Primary |
| rnz | RNZ | RSS | Primary |
| newsroom | Newsroom | RSS | Primary |
| spinoff | The Spinoff | Atom (/api/rss) |
Primary |
| interest | Interest.co.nz | RSS | Primary |
| rnz-politics | RNZ Politics | RSS | Category |
| rnz-business | RNZ Business | RSS | Category |
| rnz-national | RNZ National | RSS | Category |
| rnz-world | RNZ World | RSS | Category |
| rnz-sport | RNZ Sport | RSS | Category |
| rnz-te-ao-maori | RNZ Te Ao Māori | RSS | Category |
Primary sources are queried by default. Category feeds (RNZ sub-feeds) are available via source <id> and search --source <id>, but excluded from headlines and summary to avoid duplicate stories.
Setup
No API key required — runs on the Python 3 standard library only.
Resources
- CLI entrypoint:
scripts/cli.py - Live smoke test:
scripts/smoke_test.py
Notes
- No API key required
- No external XML parsing dependencies, uses regex-based RSS and Atom parsing
- Default output is human-readable,
--jsonoutput is for chaining into other tools or agent steps - Headlines are deduplicated by normalised title across sources
- RNZ category feeds may overlap with the main RNZ feed
Source notes
Read references/source-notes.md for source ownership, access, and freshness boundaries.