From 4adef5c58b32effe5fbc51622e1bf416cc3d4b4a Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 29 Sep 2026 07:09:38 +0000 Subject: [PATCH] Sync Treasury source integration --- src/mcp.ts | 2 +- src/scoring.ts | 5 +++++ src/sources.ts | 60 +++++++++++++++++++++++++++++++++++++++++++++++++- src/types.ts | 4 ++-- 4 files changed, 67 insertions(+), 4 deletions(-) diff --git a/src/mcp.ts b/src/mcp.ts index 7afc2a0..db0e52c 100644 --- a/src/mcp.ts +++ b/src/mcp.ts @@ -31,7 +31,7 @@ const tools = [ description: "Run ingestion now for one source or all sources.", inputSchema: { type: "object", - properties: { source_id: { type: "string", enum: ["geonet", "parliament", "stats-nz", "data-govt-nz"] } }, + properties: { source_id: { type: "string", enum: ["geonet", "parliament", "stats-nz", "data-govt-nz", "treasury"] } }, additionalProperties: false } }, diff --git a/src/scoring.ts b/src/scoring.ts index 7f954b6..a36fe98 100644 --- a/src/scoring.ts +++ b/src/scoring.ts @@ -54,5 +54,10 @@ export function scoreItem(item: NormalizedItem): ScoredItem { reasons.push("New or updated public dataset metadata"); } + if (item.sourceId === "treasury") { + score += 1; + reasons.push("New or updated Treasury publication"); + } + return { score, reasons }; } diff --git a/src/sources.ts b/src/sources.ts index 6856ffb..b3bd372 100644 --- a/src/sources.ts +++ b/src/sources.ts @@ -26,6 +26,12 @@ export const SOURCES: SourceDefinition[] = [ name: "data.govt.nz catalogue", type: "ckan", url: "https://catalogue.data.govt.nz/api/3/action/package_search?sort=metadata_modified%20desc&rows=25" + }, + { + id: "treasury", + name: "New Zealand Treasury publications", + type: "rss", + url: "https://www.treasury.govt.nz/feeds/publications" } ]; @@ -53,7 +59,8 @@ export async function fetchSource(id: SourceId): Promise { if (id === "geonet") return fetchGeoNet(); if (id === "parliament") return fetchParliament(); if (id === "stats-nz") return fetchStatsNz(); - return fetchDataGovtNz(); + if (id === "data-govt-nz") return fetchDataGovtNz(); + return fetchTreasury(); } async function fetchGeoNet(): Promise { @@ -444,3 +451,54 @@ async function fetchDataGovtNz(): Promise { raw: pkg })); } + + +async function fetchTreasury(): Promise { + const source = SOURCES.find((s) => s.id === "treasury")!; + const xml = await getText( + source.url, + "application/rss+xml,application/xml,text/xml;q=0.9,*/*;q=0.5" + ); + const parser = new XMLParser({ ignoreAttributes: false, attributeNamePrefix: "@_" }); + const parsed = parser.parse(xml); + let list = asArray(parsed?.rss?.channel?.item ?? parsed?.feed?.entry); + if (!list.length) list = rawFeedItems(xml); + + return list.slice(0, 40).map((entry: any, index: number) => { + const title = cleanXmlText( + entry.title?.["#text"] ?? + entry.title ?? + entry["atom:title"]?.["#text"] ?? + entry["atom:title"] ?? + "Treasury publication" + ); + const summary = cleanXmlText( + entry.description?.["#text"] ?? + entry.description ?? + entry.summary?.["#text"] ?? + entry.summary ?? + entry.content ?? + "" + ); + const url = firstLink(entry.link ?? entry["atom:link"]) || source.url; + const publishedAt = + cleanXmlText( + entry.pubDate ?? + entry.published ?? + entry.updated ?? + entry["dc:date"] ?? + "" + ) || null; + + return { + sourceId: "treasury" as const, + externalId: String(entry.guid?.["#text"] ?? entry.guid ?? entry.id ?? url ?? index), + title, + summary, + url, + publishedAt, + topics: ["treasury", "economy", "public-finance", "new-zealand"], + raw: entry + }; + }).filter((item: NormalizedItem) => item.title && item.url); +} diff --git a/src/types.ts b/src/types.ts index 4108a34..bdbcf29 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,9 +1,9 @@ -export type SourceId = "geonet" | "parliament" | "stats-nz" | "data-govt-nz"; +export type SourceId = "geonet" | "parliament" | "stats-nz" | "data-govt-nz" | "treasury"; export interface SourceDefinition { id: SourceId; name: string; - type: "geojson" | "html" | "sitemap" | "ckan"; + type: "geojson" | "html" | "sitemap" | "ckan" | "rss"; url: string; }