ibge-br-mcp 3.2.0 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -0
- package/dist/cache.d.ts +29 -0
- package/dist/cache.d.ts.map +1 -1
- package/dist/cache.js +38 -0
- package/dist/cache.js.map +1 -1
- package/dist/provenance.d.ts +172 -0
- package/dist/provenance.d.ts.map +1 -0
- package/dist/provenance.js +191 -0
- package/dist/provenance.js.map +1 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +23 -22
- package/dist/server.js.map +1 -1
- package/dist/structured.d.ts +10 -0
- package/dist/structured.d.ts.map +1 -1
- package/dist/structured.js +16 -0
- package/dist/structured.js.map +1 -1
- package/dist/tools/calendario.d.ts.map +1 -1
- package/dist/tools/calendario.js +7 -0
- package/dist/tools/calendario.js.map +1 -1
- package/dist/tools/censo.d.ts.map +1 -1
- package/dist/tools/censo.js +21 -2
- package/dist/tools/censo.js.map +1 -1
- package/dist/tools/cidades.d.ts.map +1 -1
- package/dist/tools/cidades.js +63 -3
- package/dist/tools/cidades.js.map +1 -1
- package/dist/tools/cnae.d.ts.map +1 -1
- package/dist/tools/cnae.js +28 -1
- package/dist/tools/cnae.js.map +1 -1
- package/dist/tools/comparar.d.ts +1 -1
- package/dist/tools/comparar.d.ts.map +1 -1
- package/dist/tools/comparar.js +36 -4
- package/dist/tools/comparar.js.map +1 -1
- package/dist/tools/datasaude.d.ts.map +1 -1
- package/dist/tools/datasaude.js +26 -1
- package/dist/tools/datasaude.js.map +1 -1
- package/dist/tools/estados.d.ts.map +1 -1
- package/dist/tools/estados.js +17 -2
- package/dist/tools/estados.js.map +1 -1
- package/dist/tools/geocodigo.d.ts.map +1 -1
- package/dist/tools/geocodigo.js +31 -0
- package/dist/tools/geocodigo.js.map +1 -1
- package/dist/tools/indicadores.d.ts.map +1 -1
- package/dist/tools/indicadores.js +40 -4
- package/dist/tools/indicadores.js.map +1 -1
- package/dist/tools/localidade.d.ts.map +1 -1
- package/dist/tools/localidade.js +15 -3
- package/dist/tools/localidade.js.map +1 -1
- package/dist/tools/malhas-tema.d.ts.map +1 -1
- package/dist/tools/malhas-tema.js +29 -3
- package/dist/tools/malhas-tema.js.map +1 -1
- package/dist/tools/malhas.d.ts.map +1 -1
- package/dist/tools/malhas.js +12 -0
- package/dist/tools/malhas.js.map +1 -1
- package/dist/tools/municipios.d.ts.map +1 -1
- package/dist/tools/municipios.js +11 -1
- package/dist/tools/municipios.js.map +1 -1
- package/dist/tools/nomes.d.ts.map +1 -1
- package/dist/tools/nomes.js +13 -0
- package/dist/tools/nomes.js.map +1 -1
- package/dist/tools/noticias.d.ts.map +1 -1
- package/dist/tools/noticias.js +7 -0
- package/dist/tools/noticias.js.map +1 -1
- package/dist/tools/paises.d.ts.map +1 -1
- package/dist/tools/paises.js +26 -2
- package/dist/tools/paises.js.map +1 -1
- package/dist/tools/pesquisas.d.ts.map +1 -1
- package/dist/tools/pesquisas.js +20 -2
- package/dist/tools/pesquisas.js.map +1 -1
- package/dist/tools/populacao.d.ts.map +1 -1
- package/dist/tools/populacao.js +7 -0
- package/dist/tools/populacao.js.map +1 -1
- package/dist/tools/sidra-metadados.d.ts.map +1 -1
- package/dist/tools/sidra-metadados.js +8 -0
- package/dist/tools/sidra-metadados.js.map +1 -1
- package/dist/tools/sidra-tabelas.d.ts.map +1 -1
- package/dist/tools/sidra-tabelas.js +11 -1
- package/dist/tools/sidra-tabelas.js.map +1 -1
- package/dist/tools/sidra.d.ts.map +1 -1
- package/dist/tools/sidra.js +28 -8
- package/dist/tools/sidra.js.map +1 -1
- package/dist/tools/vizinhos.d.ts.map +1 -1
- package/dist/tools/vizinhos.js +11 -0
- package/dist/tools/vizinhos.js.map +1 -1
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -36,6 +36,9 @@ The answers come live from the official IBGE APIs — exact figures with the tab
|
|
|
36
36
|
## Features
|
|
37
37
|
|
|
38
38
|
- **22 specialized tools** covering all major IBGE data domains
|
|
39
|
+
- **Provenance block on every response** — source, canonical URL, reference
|
|
40
|
+
period, real extraction timestamp, ready-to-use citation, and legal regime
|
|
41
|
+
(see [Data provenance](#data-provenance))
|
|
39
42
|
- **Reference resources & analysis prompts** (MCP catalogs + ready-made templates)
|
|
40
43
|
- **460 automated tests** with 97%+ core coverage
|
|
41
44
|
- **Automatic caching** with configurable TTL for optimal performance
|
|
@@ -44,6 +47,31 @@ The answers come live from the official IBGE APIs — exact figures with the tab
|
|
|
44
47
|
- **Standardized error handling** with helpful suggestions
|
|
45
48
|
- **Full TypeScript support** with strict typing
|
|
46
49
|
|
|
50
|
+
## Data provenance
|
|
51
|
+
|
|
52
|
+
Since v3.3.0 every successful tool response carries a **provenance block**
|
|
53
|
+
([portfolio contract v1.0](https://www.npmjs.com/package/@sbissoli/mcp-provenance)),
|
|
54
|
+
so each number is citable, auditable, and reproducible. The block is emitted on
|
|
55
|
+
three channels:
|
|
56
|
+
|
|
57
|
+
1. `structuredContent.provenance` (parseable, visible to the model) — exactly
|
|
58
|
+
six keys: `source` (the IBGE API queried), `source_url` (canonical URL that
|
|
59
|
+
reproduces the query), `data_vintage` (reference period when the source
|
|
60
|
+
exposes one; `null` otherwise), `retrieved_at` (the REAL upstream extraction
|
|
61
|
+
instant, preserved across cache hits, Brasília time), `citation`
|
|
62
|
+
("Fonte: IBGE — [pesquisa/tabela], [URL], extraído em [data]."), and
|
|
63
|
+
`license` — plus `attribution`, the canonical list of source URLs.
|
|
64
|
+
2. `_meta` under `br.com.sidneybissoli.ibge/provenance` and `.../attribution`
|
|
65
|
+
(out-of-band mirror for audit/UI, zero model tokens).
|
|
66
|
+
3. A compact text footer appended to the Markdown, for text-only clients.
|
|
67
|
+
|
|
68
|
+
The IBGE APIs declare no license of their own; the legal regime is Brazil's
|
|
69
|
+
open-data framework — Lei 12.527/2011 (LAI) and Decreto 8.777/2016
|
|
70
|
+
(unrestricted reuse, free use, obligation limited to crediting the source).
|
|
71
|
+
Statistics-mode responses (`estatisticas=true`) and `ibge_comparar` are marked
|
|
72
|
+
`derived` with an explanatory note in the canonical block, since the
|
|
73
|
+
aggregates are computed server-side from the raw IBGE values.
|
|
74
|
+
|
|
47
75
|
## Available Tools
|
|
48
76
|
|
|
49
77
|
### Localities & Geography
|
package/dist/cache.d.ts
CHANGED
|
@@ -2,8 +2,19 @@
|
|
|
2
2
|
* Simple in-memory cache with TTL support for IBGE API requests
|
|
3
3
|
*/
|
|
4
4
|
import { type RetryOptions } from "./retry.js";
|
|
5
|
+
/**
|
|
6
|
+
* Metadata of the last `cachedFetch` call for a cache key: the REAL instant the
|
|
7
|
+
* data was extracted from the upstream (preserved across cache hits — it is the
|
|
8
|
+
* legally relevant extraction date for the provenance block) and whether that
|
|
9
|
+
* last call was served from cache.
|
|
10
|
+
*/
|
|
11
|
+
export interface FetchMeta {
|
|
12
|
+
retrievedAt: Date;
|
|
13
|
+
servedFromCache: boolean;
|
|
14
|
+
}
|
|
5
15
|
declare class RequestCache {
|
|
6
16
|
private cache;
|
|
17
|
+
private fetchMeta;
|
|
7
18
|
private defaultTTL;
|
|
8
19
|
constructor(defaultTTLMinutes?: number);
|
|
9
20
|
/**
|
|
@@ -26,6 +37,16 @@ declare class RequestCache {
|
|
|
26
37
|
* Clear all cached data
|
|
27
38
|
*/
|
|
28
39
|
clear(): void;
|
|
40
|
+
/** Records a real upstream fetch for a key (called by `cachedFetch` on a miss). */
|
|
41
|
+
recordFetch(key: string, retrievedAt: number): void;
|
|
42
|
+
/**
|
|
43
|
+
* Records a cache hit for a key, preserving the original fetch instant.
|
|
44
|
+
* Entries seeded via `set()` directly (tests) have no recorded fetch; the hit
|
|
45
|
+
* instant is the best available approximation then.
|
|
46
|
+
*/
|
|
47
|
+
recordHit(key: string): void;
|
|
48
|
+
/** Fetch metadata of the last `cachedFetch` call for this key, if any. */
|
|
49
|
+
meta(key: string): FetchMeta | null;
|
|
29
50
|
/**
|
|
30
51
|
* Remove all expired entries
|
|
31
52
|
*/
|
|
@@ -53,5 +74,13 @@ export declare function cacheKey(base: string, params?: Record<string, string |
|
|
|
53
74
|
* Fetch with cache support and automatic retry on network failures
|
|
54
75
|
*/
|
|
55
76
|
export declare function cachedFetch<T>(url: string, cacheKeyStr: string, ttlMinutes?: number, retryOptions?: RetryOptions): Promise<T>;
|
|
77
|
+
/**
|
|
78
|
+
* Fetch metadata of the last `cachedFetch` call for a cache key — the REAL
|
|
79
|
+
* upstream extraction instant (`retrieved_at` of the provenance contract v1.0,
|
|
80
|
+
* preserved across cache hits) and whether the last call was a cache hit.
|
|
81
|
+
* Query it right after `cachedFetch` with the same key; the ~40 existing call
|
|
82
|
+
* sites stay unchanged (parallel-map design, `ibge/docs/03` §3).
|
|
83
|
+
*/
|
|
84
|
+
export declare function lastFetchMeta(cacheKeyStr: string): FetchMeta | null;
|
|
56
85
|
export {};
|
|
57
86
|
//# sourceMappingURL=cache.d.ts.map
|
package/dist/cache.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAO/D,cAAM,YAAY;IAChB,OAAO,CAAC,KAAK,CAA+C;IAC5D,OAAO,CAAC,UAAU,CAAS;gBAEf,iBAAiB,GAAE,MAAW;IAI1C;;OAEG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI;IAY7B;;OAEG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI;IAQvD;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIzB;;OAEG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAO/D;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACxB,WAAW,EAAE,IAAI,CAAC;IAClB,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,cAAM,YAAY;IAChB,OAAO,CAAC,KAAK,CAA+C;IAC5D,OAAO,CAAC,SAAS,CAA6E;IAC9F,OAAO,CAAC,UAAU,CAAS;gBAEf,iBAAiB,GAAE,MAAW;IAI1C;;OAEG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI;IAY7B;;OAEG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI;IAQvD;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIzB;;OAEG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAKzB;;OAEG;IACH,KAAK,IAAI,IAAI;IAKb,mFAAmF;IACnF,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI;IAInD;;;;OAIG;IACH,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAQ5B,0EAA0E;IAC1E,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAMnC;;OAEG;IACH,OAAO,IAAI,IAAI;IASf;;OAEG;IACH,KAAK,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,EAAE,CAAA;KAAE;CAO1C;AAGD,eAAO,MAAM,KAAK,cAAuB,CAAC;AAG1C,eAAO,MAAM,SAAS;;;;;CAKZ,CAAC;AAEX;;GAEG;AACH,wBAAgB,QAAQ,CACtB,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,GAC7D,MAAM,CAUR;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,CAAC,EACjC,GAAG,EAAE,MAAM,EACX,WAAW,EAAE,MAAM,EACnB,UAAU,CAAC,EAAE,MAAM,EACnB,YAAY,CAAC,EAAE,YAAY,GAC1B,OAAO,CAAC,CAAC,CAAC,CAsBZ;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAEnE"}
|
package/dist/cache.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { fetchWithRetry } from "./retry.js";
|
|
5
5
|
class RequestCache {
|
|
6
6
|
cache = new Map();
|
|
7
|
+
fetchMeta = new Map();
|
|
7
8
|
defaultTTL;
|
|
8
9
|
constructor(defaultTTLMinutes = 15) {
|
|
9
10
|
this.defaultTTL = defaultTTLMinutes * 60 * 1000;
|
|
@@ -42,12 +43,37 @@ class RequestCache {
|
|
|
42
43
|
*/
|
|
43
44
|
delete(key) {
|
|
44
45
|
this.cache.delete(key);
|
|
46
|
+
this.fetchMeta.delete(key);
|
|
45
47
|
}
|
|
46
48
|
/**
|
|
47
49
|
* Clear all cached data
|
|
48
50
|
*/
|
|
49
51
|
clear() {
|
|
50
52
|
this.cache.clear();
|
|
53
|
+
this.fetchMeta.clear();
|
|
54
|
+
}
|
|
55
|
+
/** Records a real upstream fetch for a key (called by `cachedFetch` on a miss). */
|
|
56
|
+
recordFetch(key, retrievedAt) {
|
|
57
|
+
this.fetchMeta.set(key, { retrievedAt, servedFromCache: false });
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Records a cache hit for a key, preserving the original fetch instant.
|
|
61
|
+
* Entries seeded via `set()` directly (tests) have no recorded fetch; the hit
|
|
62
|
+
* instant is the best available approximation then.
|
|
63
|
+
*/
|
|
64
|
+
recordHit(key) {
|
|
65
|
+
const existing = this.fetchMeta.get(key);
|
|
66
|
+
this.fetchMeta.set(key, {
|
|
67
|
+
retrievedAt: existing?.retrievedAt ?? Date.now(),
|
|
68
|
+
servedFromCache: true,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
/** Fetch metadata of the last `cachedFetch` call for this key, if any. */
|
|
72
|
+
meta(key) {
|
|
73
|
+
const m = this.fetchMeta.get(key);
|
|
74
|
+
if (!m)
|
|
75
|
+
return null;
|
|
76
|
+
return { retrievedAt: new Date(m.retrievedAt), servedFromCache: m.servedFromCache };
|
|
51
77
|
}
|
|
52
78
|
/**
|
|
53
79
|
* Remove all expired entries
|
|
@@ -100,6 +126,7 @@ export async function cachedFetch(url, cacheKeyStr, ttlMinutes, retryOptions) {
|
|
|
100
126
|
// Check cache first
|
|
101
127
|
const cached = cache.get(cacheKeyStr);
|
|
102
128
|
if (cached !== null) {
|
|
129
|
+
cache.recordHit(cacheKeyStr);
|
|
103
130
|
return cached;
|
|
104
131
|
}
|
|
105
132
|
// Fetch from API with retry support
|
|
@@ -110,6 +137,17 @@ export async function cachedFetch(url, cacheKeyStr, ttlMinutes, retryOptions) {
|
|
|
110
137
|
const data = (await response.json());
|
|
111
138
|
// Store in cache
|
|
112
139
|
cache.set(cacheKeyStr, data, ttlMinutes);
|
|
140
|
+
cache.recordFetch(cacheKeyStr, Date.now());
|
|
113
141
|
return data;
|
|
114
142
|
}
|
|
143
|
+
/**
|
|
144
|
+
* Fetch metadata of the last `cachedFetch` call for a cache key — the REAL
|
|
145
|
+
* upstream extraction instant (`retrieved_at` of the provenance contract v1.0,
|
|
146
|
+
* preserved across cache hits) and whether the last call was a cache hit.
|
|
147
|
+
* Query it right after `cachedFetch` with the same key; the ~40 existing call
|
|
148
|
+
* sites stay unchanged (parallel-map design, `ibge/docs/03` §3).
|
|
149
|
+
*/
|
|
150
|
+
export function lastFetchMeta(cacheKeyStr) {
|
|
151
|
+
return cache.meta(cacheKeyStr);
|
|
152
|
+
}
|
|
115
153
|
//# sourceMappingURL=cache.js.map
|
package/dist/cache.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAqB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provenance block (portfolio contract v1.0) — pt-BR adapter over
|
|
3
|
+
* `@sbissoli/mcp-provenance`. The canonical model, the `concise`/`detailed`
|
|
4
|
+
* projections, serialization determinism, timezone handling and the footer
|
|
5
|
+
* wording live in the package; this module binds them to the IBGE server:
|
|
6
|
+
*
|
|
7
|
+
* - one `ProvenanceContext` for the whole server (namespace
|
|
8
|
+
* `br.com.sidneybissoli.ibge`, pt-BR footer, Brasília time, `concise` mode);
|
|
9
|
+
* - the source registry (`FONTES_IBGE`) — one entry per IBGE API consumed;
|
|
10
|
+
* - the normative license block (no explicit license upstream — the legal
|
|
11
|
+
* basis is LAI + Decreto 8.777/2016, verbatim verification `ibge/docs/01`,
|
|
12
|
+
* 2026-08-08). Never use the IBGE logo/brand;
|
|
13
|
+
* - `provenienciaIbge(...)`, the per-call builder every tool uses. It pulls
|
|
14
|
+
* the REAL extraction instant (`retrieved_at`) and `served_from_cache` from
|
|
15
|
+
* the cache layer via `lastFetchMeta` (contract: cache hits keep the
|
|
16
|
+
* original fetch instant — it is the legally relevant extraction date).
|
|
17
|
+
*
|
|
18
|
+
* Emission happens in `toMcpResult` (`structured.ts`): tools attach the
|
|
19
|
+
* canonical block to their `StructuredToolResult` and the handler emits the
|
|
20
|
+
* three channels — `structuredContent.provenance` + `attribution` (parseable,
|
|
21
|
+
* visible to the model), `_meta` under namespaced keys (out-of-band, zero
|
|
22
|
+
* model tokens), and the compact text footer appended to the Markdown.
|
|
23
|
+
*
|
|
24
|
+
* `derived` semantics (same rule as senado-br-mcp): raw data that is only
|
|
25
|
+
* filtered/paginated/reserialized → `false`; the D2 statistics modes
|
|
26
|
+
* (aggregation/rankings computed server-side) → `true` + `derivation_note`.
|
|
27
|
+
*/
|
|
28
|
+
import { z } from "zod";
|
|
29
|
+
import { type CanonicalProvenance, type ConciseBlock } from "@sbissoli/mcp-provenance";
|
|
30
|
+
/** Single provenance context for the server: `_meta` namespace, locale, timezone, mode. */
|
|
31
|
+
export declare const provenanceContext: import("@sbissoli/mcp-provenance").ProvenanceContext;
|
|
32
|
+
/** Canonical envelope v1.0 (post-validation). */
|
|
33
|
+
export type Provenance = CanonicalProvenance;
|
|
34
|
+
/** Namespaced `_meta` keys (stable — audit/UI consumers read by these keys). */
|
|
35
|
+
export declare const PROVENANCE_META_KEY: string;
|
|
36
|
+
export declare const ATTRIBUTION_META_KEY: string;
|
|
37
|
+
/**
|
|
38
|
+
* Normative license block (shared by every response): the IBGE APIs declare no
|
|
39
|
+
* license of their own — the legal regime is LAI (Lei 12.527/2011) + Decreto
|
|
40
|
+
* 8.777/2016 (unrestricted reuse, free use, obligation limited to crediting
|
|
41
|
+
* the source). Verbatim verification: `ibge/docs/01`, 2026-08-08.
|
|
42
|
+
*/
|
|
43
|
+
export declare const IBGE_LICENSE: {
|
|
44
|
+
readonly id: null;
|
|
45
|
+
readonly name: "Dados abertos do Poder Executivo federal (Lei 12.527/2011; Decreto 8.777/2016)";
|
|
46
|
+
readonly url: null;
|
|
47
|
+
readonly terms_url: "https://www.planalto.gov.br/ccivil_03/_ato2015-2018/2016/decreto/d8777.htm";
|
|
48
|
+
readonly verified_at: "2026-08-08";
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Source registry — one entry per IBGE API this server consumes. `name` is
|
|
52
|
+
* what the concise projection shows as `source`; `endpoint` is the base URL
|
|
53
|
+
* actually queried. Text only, never the IBGE logo/brand (docs/01).
|
|
54
|
+
*/
|
|
55
|
+
export declare const FONTES_IBGE: {
|
|
56
|
+
readonly LOCALIDADES: {
|
|
57
|
+
readonly name: "IBGE — API de Localidades";
|
|
58
|
+
readonly endpoint: "https://servicodados.ibge.gov.br/api/v1/localidades";
|
|
59
|
+
};
|
|
60
|
+
readonly SIDRA: {
|
|
61
|
+
readonly name: "IBGE — SIDRA (Banco de Tabelas Estatísticas)";
|
|
62
|
+
readonly endpoint: "https://apisidra.ibge.gov.br/values";
|
|
63
|
+
};
|
|
64
|
+
readonly AGREGADOS: {
|
|
65
|
+
readonly name: "IBGE — API de Agregados (SIDRA)";
|
|
66
|
+
readonly endpoint: "https://servicodados.ibge.gov.br/api/v3/agregados";
|
|
67
|
+
};
|
|
68
|
+
readonly NOMES: {
|
|
69
|
+
readonly name: "IBGE — API de Nomes (Censo Demográfico 2010)";
|
|
70
|
+
readonly endpoint: "https://servicodados.ibge.gov.br/api/v2/censos/nomes";
|
|
71
|
+
};
|
|
72
|
+
readonly MALHAS: {
|
|
73
|
+
readonly name: "IBGE — API de Malhas Geográficas";
|
|
74
|
+
readonly endpoint: "https://servicodados.ibge.gov.br/api/v3/malhas";
|
|
75
|
+
};
|
|
76
|
+
readonly NOTICIAS: {
|
|
77
|
+
readonly name: "IBGE — API de Notícias";
|
|
78
|
+
readonly endpoint: "https://servicodados.ibge.gov.br/api/v3/noticias";
|
|
79
|
+
};
|
|
80
|
+
readonly POPULACAO: {
|
|
81
|
+
readonly name: "IBGE — API de Projeções de População";
|
|
82
|
+
readonly endpoint: "https://servicodados.ibge.gov.br/api/v1/projecoes/populacao";
|
|
83
|
+
};
|
|
84
|
+
readonly CNAE: {
|
|
85
|
+
readonly name: "IBGE — API CNAE";
|
|
86
|
+
readonly endpoint: "https://servicodados.ibge.gov.br/api/v2/cnae";
|
|
87
|
+
};
|
|
88
|
+
readonly CALENDARIO: {
|
|
89
|
+
readonly name: "IBGE — API de Calendário de Divulgações";
|
|
90
|
+
readonly endpoint: "https://servicodados.ibge.gov.br/api/v3/calendario";
|
|
91
|
+
};
|
|
92
|
+
readonly PAISES: {
|
|
93
|
+
readonly name: "IBGE — API de Países";
|
|
94
|
+
readonly endpoint: "https://servicodados.ibge.gov.br/api/v1/paises";
|
|
95
|
+
};
|
|
96
|
+
readonly PESQUISAS: {
|
|
97
|
+
readonly name: "IBGE — API de Pesquisas (Cidades@)";
|
|
98
|
+
readonly endpoint: "https://servicodados.ibge.gov.br/api/v1/pesquisas";
|
|
99
|
+
};
|
|
100
|
+
};
|
|
101
|
+
export type FonteIbge = keyof typeof FONTES_IBGE;
|
|
102
|
+
export interface ProvenienciaIbgeOptions {
|
|
103
|
+
/** Which IBGE API answered this response. */
|
|
104
|
+
fonte: FonteIbge;
|
|
105
|
+
/** The URL effectively queried (canonical reproduction of the request). */
|
|
106
|
+
url: string;
|
|
107
|
+
/**
|
|
108
|
+
* Cache key of the main `cachedFetch` call — used to pull the REAL upstream
|
|
109
|
+
* extraction instant and `served_from_cache` from the cache layer. Omit only
|
|
110
|
+
* for static catalogs maintained in code (contract: builder default).
|
|
111
|
+
*/
|
|
112
|
+
chaveCache?: string;
|
|
113
|
+
/** "[pesquisa/tabela]" of the citation, e.g. "SIDRA, Tabela 6579 (Estimativas de população)". */
|
|
114
|
+
pesquisa: string;
|
|
115
|
+
/** Dataset identifier within the source (e.g. the SIDRA table code), when there is one. */
|
|
116
|
+
dataset?: string;
|
|
117
|
+
/** Reference period exposed by the source (SIDRA period); null/omitted when not exposed. */
|
|
118
|
+
dataVintage?: string | null;
|
|
119
|
+
/** D2 statistics modes: the server derived aggregates from the raw records. */
|
|
120
|
+
derivado?: {
|
|
121
|
+
nota: string;
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Builds the canonical provenance block for one tool response. Citation
|
|
126
|
+
* follows the pattern fixed by the verbatim verification (docs/01):
|
|
127
|
+
* "Fonte: IBGE — [pesquisa/tabela], [URL], extraído em [data]."
|
|
128
|
+
*/
|
|
129
|
+
export declare function provenienciaIbge(opts: ProvenienciaIbgeOptions): Provenance;
|
|
130
|
+
/** Fixed derivation note for the D2 statistics modes (estatisticas/agruparPor/topN). */
|
|
131
|
+
export declare const NOTA_DERIVACAO_ESTATISTICAS = "Estat\u00EDsticas (distribui\u00E7\u00E3o, agregados e rankings) computadas pelo servidor a partir dos registros brutos retornados pela fonte; os valores individuais permanecem os originais do IBGE.";
|
|
132
|
+
/**
|
|
133
|
+
* Reference period of a SIDRA-style result, extracted from the standard period
|
|
134
|
+
* column when the source exposes one (docs/03: "período SIDRA quando exposto;
|
|
135
|
+
* null senão"). Distinct values are joined as a deterministic range
|
|
136
|
+
* ("2022" or "2020–2023"); no period column → null.
|
|
137
|
+
*/
|
|
138
|
+
export declare function extrairPeriodoSidra(colunas: string[], registros: Array<Record<string, string>>): string | null;
|
|
139
|
+
/** Concise projection of a block (the shape embedded in `structuredContent`/`_meta`). */
|
|
140
|
+
export declare const provenanceBlockSchema: z.ZodObject<{
|
|
141
|
+
source: z.ZodString;
|
|
142
|
+
source_url: z.ZodString;
|
|
143
|
+
data_vintage: z.ZodNullable<z.ZodString>;
|
|
144
|
+
retrieved_at: z.ZodString;
|
|
145
|
+
citation: z.ZodString;
|
|
146
|
+
license: z.ZodNullable<z.ZodString>;
|
|
147
|
+
}, z.core.$strip>;
|
|
148
|
+
/**
|
|
149
|
+
* Extends a tool's output schema with the provenance channel of the contract
|
|
150
|
+
* v1.0: the concise block + the `attribution` URL list (MCP RFC #711). Every
|
|
151
|
+
* successful response carries both (wired in `toMcpResult`).
|
|
152
|
+
*/
|
|
153
|
+
export declare function comProveniencia<T extends z.ZodObject<z.ZodRawShape>>(schema: T): z.ZodObject<{
|
|
154
|
+
readonly [x: string]: z.core.$ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>;
|
|
155
|
+
provenance: z.ZodObject<{
|
|
156
|
+
source: z.ZodString;
|
|
157
|
+
source_url: z.ZodString;
|
|
158
|
+
data_vintage: z.ZodNullable<z.ZodString>;
|
|
159
|
+
retrieved_at: z.ZodString;
|
|
160
|
+
citation: z.ZodString;
|
|
161
|
+
license: z.ZodNullable<z.ZodString>;
|
|
162
|
+
}, z.core.$strip>;
|
|
163
|
+
attribution: z.ZodArray<z.ZodString>;
|
|
164
|
+
}, z.core.$strip>;
|
|
165
|
+
/** Concise projection + attribution list for a block (used by `toMcpResult`). */
|
|
166
|
+
export declare function projetarProveniencia(p: Provenance): {
|
|
167
|
+
provenance: ConciseBlock;
|
|
168
|
+
attribution: string[];
|
|
169
|
+
};
|
|
170
|
+
/** Compact text footer for the Markdown channel (fixed wording, contract v1.0). */
|
|
171
|
+
export declare function rodapeProveniencia(p: Provenance): string;
|
|
172
|
+
//# sourceMappingURL=provenance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provenance.d.ts","sourceRoot":"","sources":["../src/provenance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAIL,KAAK,mBAAmB,EACxB,KAAK,YAAY,EAClB,MAAM,0BAA0B,CAAC;AAIlC,2FAA2F;AAC3F,eAAO,MAAM,iBAAiB,sDAK5B,CAAC;AAEH,iDAAiD;AACjD,MAAM,MAAM,UAAU,GAAG,mBAAmB,CAAC;AAE7C,gFAAgF;AAChF,eAAO,MAAM,mBAAmB,QAAwC,CAAC;AACzE,eAAO,MAAM,oBAAoB,QAAyC,CAAC;AAE3E;;;;;GAKG;AACH,eAAO,MAAM,YAAY;;;;;;CAMf,CAAC;AAEX;;;;GAIG;AACH,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6Cd,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,MAAM,OAAO,WAAW,CAAC;AAajD,MAAM,WAAW,uBAAuB;IACtC,6CAA6C;IAC7C,KAAK,EAAE,SAAS,CAAC;IACjB,2EAA2E;IAC3E,GAAG,EAAE,MAAM,CAAC;IACZ;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iGAAiG;IACjG,QAAQ,EAAE,MAAM,CAAC;IACjB,2FAA2F;IAC3F,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4FAA4F;IAC5F,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,+EAA+E;IAC/E,QAAQ,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7B;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,uBAAuB,GAAG,UAAU,CAiB1E;AAED,wFAAwF;AACxF,eAAO,MAAM,2BAA2B,2MACmJ,CAAC;AAE5L;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EAAE,EACjB,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GACvC,MAAM,GAAG,IAAI,CAYf;AAED,yFAAyF;AACzF,eAAO,MAAM,qBAAqB;;;;;;;iBAUhC,CAAC;AAEH;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;;;;;;;;;;;kBAS9E;AAED,iFAAiF;AACjF,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,UAAU,GAAG;IACnD,UAAU,EAAE,YAAY,CAAC;IACzB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB,CAEA;AAED,mFAAmF;AACnF,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,UAAU,GAAG,MAAM,CAExD"}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provenance block (portfolio contract v1.0) — pt-BR adapter over
|
|
3
|
+
* `@sbissoli/mcp-provenance`. The canonical model, the `concise`/`detailed`
|
|
4
|
+
* projections, serialization determinism, timezone handling and the footer
|
|
5
|
+
* wording live in the package; this module binds them to the IBGE server:
|
|
6
|
+
*
|
|
7
|
+
* - one `ProvenanceContext` for the whole server (namespace
|
|
8
|
+
* `br.com.sidneybissoli.ibge`, pt-BR footer, Brasília time, `concise` mode);
|
|
9
|
+
* - the source registry (`FONTES_IBGE`) — one entry per IBGE API consumed;
|
|
10
|
+
* - the normative license block (no explicit license upstream — the legal
|
|
11
|
+
* basis is LAI + Decreto 8.777/2016, verbatim verification `ibge/docs/01`,
|
|
12
|
+
* 2026-08-08). Never use the IBGE logo/brand;
|
|
13
|
+
* - `provenienciaIbge(...)`, the per-call builder every tool uses. It pulls
|
|
14
|
+
* the REAL extraction instant (`retrieved_at`) and `served_from_cache` from
|
|
15
|
+
* the cache layer via `lastFetchMeta` (contract: cache hits keep the
|
|
16
|
+
* original fetch instant — it is the legally relevant extraction date).
|
|
17
|
+
*
|
|
18
|
+
* Emission happens in `toMcpResult` (`structured.ts`): tools attach the
|
|
19
|
+
* canonical block to their `StructuredToolResult` and the handler emits the
|
|
20
|
+
* three channels — `structuredContent.provenance` + `attribution` (parseable,
|
|
21
|
+
* visible to the model), `_meta` under namespaced keys (out-of-band, zero
|
|
22
|
+
* model tokens), and the compact text footer appended to the Markdown.
|
|
23
|
+
*
|
|
24
|
+
* `derived` semantics (same rule as senado-br-mcp): raw data that is only
|
|
25
|
+
* filtered/paginated/reserialized → `false`; the D2 statistics modes
|
|
26
|
+
* (aggregation/rankings computed server-side) → `true` + `derivation_note`.
|
|
27
|
+
*/
|
|
28
|
+
import { z } from "zod";
|
|
29
|
+
import { attributionList, createProvenanceContext, renderConcise, } from "@sbissoli/mcp-provenance";
|
|
30
|
+
import { lastFetchMeta } from "./cache.js";
|
|
31
|
+
import { API_ENDPOINTS } from "./config.js";
|
|
32
|
+
/** Single provenance context for the server: `_meta` namespace, locale, timezone, mode. */
|
|
33
|
+
export const provenanceContext = createProvenanceContext({
|
|
34
|
+
metaNamespace: "br.com.sidneybissoli.ibge",
|
|
35
|
+
locale: "pt-BR",
|
|
36
|
+
timezone: { offset: "-03:00", label: "horário de Brasília" },
|
|
37
|
+
defaultMode: "concise",
|
|
38
|
+
});
|
|
39
|
+
/** Namespaced `_meta` keys (stable — audit/UI consumers read by these keys). */
|
|
40
|
+
export const PROVENANCE_META_KEY = provenanceContext.metaKeys.provenance;
|
|
41
|
+
export const ATTRIBUTION_META_KEY = provenanceContext.metaKeys.attribution;
|
|
42
|
+
/**
|
|
43
|
+
* Normative license block (shared by every response): the IBGE APIs declare no
|
|
44
|
+
* license of their own — the legal regime is LAI (Lei 12.527/2011) + Decreto
|
|
45
|
+
* 8.777/2016 (unrestricted reuse, free use, obligation limited to crediting
|
|
46
|
+
* the source). Verbatim verification: `ibge/docs/01`, 2026-08-08.
|
|
47
|
+
*/
|
|
48
|
+
export const IBGE_LICENSE = {
|
|
49
|
+
id: null,
|
|
50
|
+
name: "Dados abertos do Poder Executivo federal (Lei 12.527/2011; Decreto 8.777/2016)",
|
|
51
|
+
url: null,
|
|
52
|
+
terms_url: "https://www.planalto.gov.br/ccivil_03/_ato2015-2018/2016/decreto/d8777.htm",
|
|
53
|
+
verified_at: "2026-08-08",
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Source registry — one entry per IBGE API this server consumes. `name` is
|
|
57
|
+
* what the concise projection shows as `source`; `endpoint` is the base URL
|
|
58
|
+
* actually queried. Text only, never the IBGE logo/brand (docs/01).
|
|
59
|
+
*/
|
|
60
|
+
export const FONTES_IBGE = {
|
|
61
|
+
LOCALIDADES: {
|
|
62
|
+
name: "IBGE — API de Localidades",
|
|
63
|
+
endpoint: API_ENDPOINTS.IBGE.LOCALIDADES,
|
|
64
|
+
},
|
|
65
|
+
SIDRA: {
|
|
66
|
+
name: "IBGE — SIDRA (Banco de Tabelas Estatísticas)",
|
|
67
|
+
endpoint: API_ENDPOINTS.SIDRA,
|
|
68
|
+
},
|
|
69
|
+
AGREGADOS: {
|
|
70
|
+
name: "IBGE — API de Agregados (SIDRA)",
|
|
71
|
+
endpoint: API_ENDPOINTS.IBGE.AGREGADOS,
|
|
72
|
+
},
|
|
73
|
+
NOMES: {
|
|
74
|
+
name: "IBGE — API de Nomes (Censo Demográfico 2010)",
|
|
75
|
+
endpoint: API_ENDPOINTS.IBGE.NOMES,
|
|
76
|
+
},
|
|
77
|
+
MALHAS: {
|
|
78
|
+
name: "IBGE — API de Malhas Geográficas",
|
|
79
|
+
endpoint: API_ENDPOINTS.IBGE.MALHAS,
|
|
80
|
+
},
|
|
81
|
+
NOTICIAS: {
|
|
82
|
+
name: "IBGE — API de Notícias",
|
|
83
|
+
endpoint: API_ENDPOINTS.IBGE.NOTICIAS,
|
|
84
|
+
},
|
|
85
|
+
POPULACAO: {
|
|
86
|
+
name: "IBGE — API de Projeções de População",
|
|
87
|
+
endpoint: API_ENDPOINTS.IBGE.POPULACAO,
|
|
88
|
+
},
|
|
89
|
+
CNAE: {
|
|
90
|
+
name: "IBGE — API CNAE",
|
|
91
|
+
endpoint: API_ENDPOINTS.IBGE.CNAE,
|
|
92
|
+
},
|
|
93
|
+
CALENDARIO: {
|
|
94
|
+
name: "IBGE — API de Calendário de Divulgações",
|
|
95
|
+
endpoint: API_ENDPOINTS.IBGE.CALENDARIO,
|
|
96
|
+
},
|
|
97
|
+
PAISES: {
|
|
98
|
+
name: "IBGE — API de Países",
|
|
99
|
+
endpoint: API_ENDPOINTS.IBGE.PAISES,
|
|
100
|
+
},
|
|
101
|
+
PESQUISAS: {
|
|
102
|
+
name: "IBGE — API de Pesquisas (Cidades@)",
|
|
103
|
+
endpoint: API_ENDPOINTS.IBGE.PESQUISAS,
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
/** "dd/mm/aaaa" of an instant in Brasília time, for the citation text. */
|
|
107
|
+
function dataCitacao(retrievedAt) {
|
|
108
|
+
const iso = retrievedAt instanceof Date
|
|
109
|
+
? // -03:00 fixed offset (Brazil has no DST since 2019).
|
|
110
|
+
new Date(retrievedAt.getTime() - 3 * 60 * 60 * 1000).toISOString()
|
|
111
|
+
: retrievedAt;
|
|
112
|
+
const [ano, mes, dia] = iso.slice(0, 10).split("-");
|
|
113
|
+
return `${dia}/${mes}/${ano}`;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Builds the canonical provenance block for one tool response. Citation
|
|
117
|
+
* follows the pattern fixed by the verbatim verification (docs/01):
|
|
118
|
+
* "Fonte: IBGE — [pesquisa/tabela], [URL], extraído em [data]."
|
|
119
|
+
*/
|
|
120
|
+
export function provenienciaIbge(opts) {
|
|
121
|
+
const fonte = FONTES_IBGE[opts.fonte];
|
|
122
|
+
const meta = opts.chaveCache ? lastFetchMeta(opts.chaveCache) : null;
|
|
123
|
+
const retrievedAt = meta?.retrievedAt ?? new Date();
|
|
124
|
+
return provenanceContext.build({
|
|
125
|
+
source: { name: fonte.name, agency: "IBGE", database: null, endpoint: fonte.endpoint },
|
|
126
|
+
source_url: opts.url,
|
|
127
|
+
...(opts.dataset !== undefined ? { dataset: opts.dataset } : {}),
|
|
128
|
+
data_vintage: opts.dataVintage ?? null,
|
|
129
|
+
retrieved_at: retrievedAt,
|
|
130
|
+
citation: `Fonte: IBGE — ${opts.pesquisa}, ${opts.url}, extraído em ${dataCitacao(retrievedAt)}.`,
|
|
131
|
+
license: IBGE_LICENSE,
|
|
132
|
+
derived: opts.derivado !== undefined,
|
|
133
|
+
...(opts.derivado !== undefined ? { derivation_note: opts.derivado.nota } : {}),
|
|
134
|
+
served_from_cache: meta ? meta.servedFromCache : null,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
/** Fixed derivation note for the D2 statistics modes (estatisticas/agruparPor/topN). */
|
|
138
|
+
export const NOTA_DERIVACAO_ESTATISTICAS = "Estatísticas (distribuição, agregados e rankings) computadas pelo servidor a partir dos registros brutos retornados pela fonte; os valores individuais permanecem os originais do IBGE.";
|
|
139
|
+
/**
|
|
140
|
+
* Reference period of a SIDRA-style result, extracted from the standard period
|
|
141
|
+
* column when the source exposes one (docs/03: "período SIDRA quando exposto;
|
|
142
|
+
* null senão"). Distinct values are joined as a deterministic range
|
|
143
|
+
* ("2022" or "2020–2023"); no period column → null.
|
|
144
|
+
*/
|
|
145
|
+
export function extrairPeriodoSidra(colunas, registros) {
|
|
146
|
+
const candidatas = colunas.filter((c) => /^(ano|trimestre|m[eê]s|semestre|per[ií]odo)\b/i.test(c));
|
|
147
|
+
// SIDRA exposes "(Código)"/plain column pairs — prefer the readable label.
|
|
148
|
+
const idx = candidatas.find((c) => !/\(c[oó]digo\)/i.test(c)) ?? candidatas[0];
|
|
149
|
+
if (!idx)
|
|
150
|
+
return null;
|
|
151
|
+
const valores = [
|
|
152
|
+
...new Set(registros.map((r) => r[idx]).filter((v) => Boolean(v))),
|
|
153
|
+
].sort();
|
|
154
|
+
if (valores.length === 0)
|
|
155
|
+
return null;
|
|
156
|
+
return valores.length === 1 ? valores[0] : `${valores[0]}–${valores[valores.length - 1]}`;
|
|
157
|
+
}
|
|
158
|
+
/** Concise projection of a block (the shape embedded in `structuredContent`/`_meta`). */
|
|
159
|
+
export const provenanceBlockSchema = z.object({
|
|
160
|
+
source: z.string().describe("Fonte oficial do dado (API do IBGE consultada)"),
|
|
161
|
+
source_url: z.string().describe("URL canônica que reproduz a consulta"),
|
|
162
|
+
data_vintage: z
|
|
163
|
+
.string()
|
|
164
|
+
.nullable()
|
|
165
|
+
.describe("Período de referência do dado segundo a fonte; null se a fonte não expõe"),
|
|
166
|
+
retrieved_at: z.string().describe("Instante real da extração no upstream (ISO-8601, horário de Brasília)"),
|
|
167
|
+
citation: z.string().describe("Citação pronta para uso"),
|
|
168
|
+
license: z.string().nullable().describe("Regime legal do dado"),
|
|
169
|
+
});
|
|
170
|
+
/**
|
|
171
|
+
* Extends a tool's output schema with the provenance channel of the contract
|
|
172
|
+
* v1.0: the concise block + the `attribution` URL list (MCP RFC #711). Every
|
|
173
|
+
* successful response carries both (wired in `toMcpResult`).
|
|
174
|
+
*/
|
|
175
|
+
export function comProveniencia(schema) {
|
|
176
|
+
return schema.extend({
|
|
177
|
+
provenance: provenanceBlockSchema.describe("Bloco de proveniência (contrato v1.0): fonte, URL, período, extração e licença"),
|
|
178
|
+
attribution: z
|
|
179
|
+
.array(z.string())
|
|
180
|
+
.describe("URLs canônicas das fontes desta resposta (lista de atribuição)"),
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
/** Concise projection + attribution list for a block (used by `toMcpResult`). */
|
|
184
|
+
export function projetarProveniencia(p) {
|
|
185
|
+
return { provenance: renderConcise(p), attribution: attributionList([p]) };
|
|
186
|
+
}
|
|
187
|
+
/** Compact text footer for the Markdown channel (fixed wording, contract v1.0). */
|
|
188
|
+
export function rodapeProveniencia(p) {
|
|
189
|
+
return provenanceContext.footer(p);
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=provenance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provenance.js","sourceRoot":"","sources":["../src/provenance.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAwB,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAwB,MAAM,8BAA8B,CAAC;AAqF/E,eAAO,MAAM,WAAW,gBAAgB,CAAC;AACzC,eAAO,MAAM,cAAc,QAAc,CAAC;AAE1C;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,QAYpB,CAAC;AAgBb;;;;;;;GAOG;AACH,wBAAgB,YAAY,IAAI,SAAS,CAUxC;AAED;;;;;;GAMG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,IAAI,EAAE,WAAW,GAAG,YAAY,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;AAEzF;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAk0B/E"}
|