sih-br-mcp 0.18.0 → 1.0.1

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.
@@ -0,0 +1,59 @@
1
+ /**
2
+ * `server/discover` anuncia TODAS as revisões que o servidor atende, não só as
3
+ * modernas.
4
+ *
5
+ * O ACHADO. O `mcpscore` reprovava `protocol_version_supported_versions_include_negotiated`:
6
+ * o servidor negocia 2025-11-25 pelo handshake `initialize` — é a revisão que o
7
+ * próprio auditor negocia, e a que a maioria dos clientes fala hoje — mas o
8
+ * `server/discover` anunciava só `["2026-07-28"]`. A mensagem do auditor é
9
+ * explícita sobre as duas saídas: "add it to supportedVersions, or disable the
10
+ * legacy lifecycle". Desligar o ciclo legado trocaria 1 ponto por uma regressão
11
+ * de compatibilidade com quase todos os clientes; sobra anunciar a verdade.
12
+ *
13
+ * NO SIH, A REGRA SÓ APARECE DEPOIS DA OUTRA. Até 25/09/2026 o contêiner
14
+ * atendia o HTTP por `server.connect(transport)` + `handleRequest`, o caminho
15
+ * LEGADO do SDK: não havia `server/discover` nenhum (HTTP 400 "Unsupported
16
+ * protocol version: 2026-07-28"), e o auditor reprovava a regra de cima,
17
+ * `protocol_version_latest` (MEDIUM, 2 pontos, `modern_lifecycle_support:
18
+ * false`). A entrada passou a ser `createMcpHandler` + `toNodeHandler`
19
+ * (src/http.ts), que serve as duas eras — e aí o discover existe, anuncia só a
20
+ * moderna, e este módulo completa o anúncio. No stdio o `serveStdio` já era
21
+ * dual-era, e a regra reprovava exatamente como no ilo.
22
+ *
23
+ * POR QUE O SDK NÃO FAZ ISSO. O `_ondiscover()` do
24
+ * `@modelcontextprotocol/server` 2.0.0 devolve
25
+ * `modernProtocolVersions(this._supportedProtocolVersions)`, um filtro que
26
+ * descarta por desenho toda revisão pré-2026 ("2025-era versions are negotiated
27
+ * via `initialize`"). Não há opção que o desligue. É uma leitura mais estrita
28
+ * que a do auditor, que se apoia em Basic §Versioning — onde o exemplo de
29
+ * `UnsupportedProtocolVersionError` lista revisões legadas em `supported`.
30
+ *
31
+ * POR QUE PATCH DE MÉTODO, E NÃO TROCA DE HANDLER. Registrar o nosso próprio
32
+ * handler de `server/discover` não gruda: a entrada HTTP do SDK instala
33
+ * `() => server._ondiscover()` na instância que a factory devolve, A CADA
34
+ * REQUEST, depois da nossa factory. Como o que ela instala é uma closure que
35
+ * chama o MÉTODO, trocar o método vale para os dois caminhos — o handler do
36
+ * construtor e o reinstalado — e sobrevive à reinstalação.
37
+ *
38
+ * A GUARDA. Isto mexe em `_ondiscover`, que é interno do SDK. O risco de um
39
+ * patch assim é virar silêncio: o SDK renomeia o método, o patch não aplica
40
+ * nada e ninguém percebe. Por isso `announceServedVersions` FALHA ALTO se a
41
+ * forma esperada não estiver lá — o servidor nem constrói — em vez de seguir
42
+ * com o anúncio antigo. `tests/discover.test.ts` prende o comportamento, e a
43
+ * catraca do mcpscore no CI (.github/workflows/mcpscore.yml) pega a regressão
44
+ * pelo lado de fora. Transplantado do ilo-mcp-server, a implementação de
45
+ * referência do portfólio (mesmo SDK 2.0.0).
46
+ */
47
+ import type { McpServer } from "@modelcontextprotocol/server";
48
+ /**
49
+ * Ordena revisões datadas da mais nova para a mais antiga. São strings
50
+ * `AAAA-MM-DD`, então a ordem lexicográfica É a cronológica.
51
+ */
52
+ export declare function maisNovaPrimeiro(versoes: readonly string[]): string[];
53
+ /**
54
+ * Troca o `_ondiscover` da instância por um que anuncia todas as revisões
55
+ * atendidas. Só a lista muda: capacidades e instruções continuam vindo do
56
+ * cálculo do próprio SDK.
57
+ */
58
+ export declare function announceServedVersions(server: McpServer): void;
59
+ //# sourceMappingURL=discover.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discover.d.ts","sourceRoot":"","sources":["../src/discover.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAQ9D;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAErE;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAsC9D"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * `server/discover` anuncia TODAS as revisões que o servidor atende, não só as
3
+ * modernas.
4
+ *
5
+ * O ACHADO. O `mcpscore` reprovava `protocol_version_supported_versions_include_negotiated`:
6
+ * o servidor negocia 2025-11-25 pelo handshake `initialize` — é a revisão que o
7
+ * próprio auditor negocia, e a que a maioria dos clientes fala hoje — mas o
8
+ * `server/discover` anunciava só `["2026-07-28"]`. A mensagem do auditor é
9
+ * explícita sobre as duas saídas: "add it to supportedVersions, or disable the
10
+ * legacy lifecycle". Desligar o ciclo legado trocaria 1 ponto por uma regressão
11
+ * de compatibilidade com quase todos os clientes; sobra anunciar a verdade.
12
+ *
13
+ * NO SIH, A REGRA SÓ APARECE DEPOIS DA OUTRA. Até 25/09/2026 o contêiner
14
+ * atendia o HTTP por `server.connect(transport)` + `handleRequest`, o caminho
15
+ * LEGADO do SDK: não havia `server/discover` nenhum (HTTP 400 "Unsupported
16
+ * protocol version: 2026-07-28"), e o auditor reprovava a regra de cima,
17
+ * `protocol_version_latest` (MEDIUM, 2 pontos, `modern_lifecycle_support:
18
+ * false`). A entrada passou a ser `createMcpHandler` + `toNodeHandler`
19
+ * (src/http.ts), que serve as duas eras — e aí o discover existe, anuncia só a
20
+ * moderna, e este módulo completa o anúncio. No stdio o `serveStdio` já era
21
+ * dual-era, e a regra reprovava exatamente como no ilo.
22
+ *
23
+ * POR QUE O SDK NÃO FAZ ISSO. O `_ondiscover()` do
24
+ * `@modelcontextprotocol/server` 2.0.0 devolve
25
+ * `modernProtocolVersions(this._supportedProtocolVersions)`, um filtro que
26
+ * descarta por desenho toda revisão pré-2026 ("2025-era versions are negotiated
27
+ * via `initialize`"). Não há opção que o desligue. É uma leitura mais estrita
28
+ * que a do auditor, que se apoia em Basic §Versioning — onde o exemplo de
29
+ * `UnsupportedProtocolVersionError` lista revisões legadas em `supported`.
30
+ *
31
+ * POR QUE PATCH DE MÉTODO, E NÃO TROCA DE HANDLER. Registrar o nosso próprio
32
+ * handler de `server/discover` não gruda: a entrada HTTP do SDK instala
33
+ * `() => server._ondiscover()` na instância que a factory devolve, A CADA
34
+ * REQUEST, depois da nossa factory. Como o que ela instala é uma closure que
35
+ * chama o MÉTODO, trocar o método vale para os dois caminhos — o handler do
36
+ * construtor e o reinstalado — e sobrevive à reinstalação.
37
+ *
38
+ * A GUARDA. Isto mexe em `_ondiscover`, que é interno do SDK. O risco de um
39
+ * patch assim é virar silêncio: o SDK renomeia o método, o patch não aplica
40
+ * nada e ninguém percebe. Por isso `announceServedVersions` FALHA ALTO se a
41
+ * forma esperada não estiver lá — o servidor nem constrói — em vez de seguir
42
+ * com o anúncio antigo. `tests/discover.test.ts` prende o comportamento, e a
43
+ * catraca do mcpscore no CI (.github/workflows/mcpscore.yml) pega a regressão
44
+ * pelo lado de fora. Transplantado do ilo-mcp-server, a implementação de
45
+ * referência do portfólio (mesmo SDK 2.0.0).
46
+ */
47
+ /**
48
+ * Ordena revisões datadas da mais nova para a mais antiga. São strings
49
+ * `AAAA-MM-DD`, então a ordem lexicográfica É a cronológica.
50
+ */
51
+ export function maisNovaPrimeiro(versoes) {
52
+ return [...new Set(versoes)].sort().reverse();
53
+ }
54
+ /**
55
+ * Troca o `_ondiscover` da instância por um que anuncia todas as revisões
56
+ * atendidas. Só a lista muda: capacidades e instruções continuam vindo do
57
+ * cálculo do próprio SDK.
58
+ */
59
+ export function announceServedVersions(server) {
60
+ const low = server.server;
61
+ if (typeof low._ondiscover !== "function") {
62
+ throw new Error("SDK mudou: Server._ondiscover sumiu — o anúncio de versões em src/discover.ts " +
63
+ "deixaria de aplicar em silêncio. Reveja o módulo contra a versão nova do " +
64
+ "@modelcontextprotocol/server antes de seguir.");
65
+ }
66
+ if (!Array.isArray(low._supportedProtocolVersions) ||
67
+ low._supportedProtocolVersions.some((v) => typeof v !== "string")) {
68
+ throw new Error("SDK mudou: Server._supportedProtocolVersions não é mais uma lista de strings — " +
69
+ "src/discover.ts não tem de onde tirar as revisões atendidas.");
70
+ }
71
+ const original = low._ondiscover.bind(low);
72
+ low._ondiscover = () => {
73
+ const base = original();
74
+ // LER NA HORA DA CHAMADA, não aqui na aplicação do patch. O
75
+ // `installDiscoverHandler` do SDK ACRESCENTA as revisões modernas a
76
+ // `_supportedProtocolVersions` por REATRIBUIÇÃO, já com o servidor
77
+ // construído: uma referência capturada agora ficaria presa ao array
78
+ // anterior. Foi o que aconteceu na primeira versão deste módulo no ilo — o
79
+ // anúncio saiu com as cinco revisões legadas e SEM a 2026-07-28, e a regra
80
+ // do auditor passou assim mesmo, porque ela só confere se a negociada está
81
+ // na lista. Trocar uma omissão por outra não é corrigir.
82
+ const agora = low._supportedProtocolVersions;
83
+ if (!Array.isArray(agora) || agora.some((v) => typeof v !== "string"))
84
+ return base;
85
+ // A lista vem do próprio SDK, nunca de literais nossas: anunciar uma
86
+ // revisão que o servidor não atende seria a mentira simétrica da que este
87
+ // módulo corrige.
88
+ return { ...base, supportedVersions: maisNovaPrimeiro(agora) };
89
+ };
90
+ }
91
+ //# sourceMappingURL=discover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discover.js","sourceRoot":"","sources":["../src/discover.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAUH;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAA0B;IACzD,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;AAChD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAAiB;IACtD,MAAM,GAAG,GAAG,MAAM,CAAC,MAAwC,CAAC;IAE5D,IAAI,OAAO,GAAG,CAAC,WAAW,KAAK,UAAU,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CACb,gFAAgF;YAC9E,2EAA2E;YAC3E,+CAA+C,CAClD,CAAC;IACJ,CAAC;IACD,IACE,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC;QAC9C,GAAG,CAAC,0BAA0B,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,EACjE,CAAC;QACD,MAAM,IAAI,KAAK,CACb,iFAAiF;YAC/E,8DAA8D,CACjE,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC3C,GAAG,CAAC,WAAW,GAAG,GAAG,EAAE;QACrB,MAAM,IAAI,GAAG,QAAQ,EAAE,CAAC;QACxB,4DAA4D;QAC5D,oEAAoE;QACpE,mEAAmE;QACnE,oEAAoE;QACpE,2EAA2E;QAC3E,2EAA2E;QAC3E,2EAA2E;QAC3E,yDAAyD;QACzD,MAAM,KAAK,GAAG,GAAG,CAAC,0BAA0B,CAAC;QAC7C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC;YAAE,OAAO,IAAI,CAAC;QACnF,qEAAqE;QACrE,0EAA0E;QAC1E,kBAAkB;QAClB,OAAO,EAAE,GAAG,IAAI,EAAE,iBAAiB,EAAE,gBAAgB,CAAC,KAAiB,CAAC,EAAE,CAAC;IAC7E,CAAC,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":";AAoCA,eAAO,MAAM,QAAQ,SAAS,CAAC"}
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":";AAqDA,eAAO,MAAM,QAAQ,SAAS,CAAC"}
package/dist/http.js CHANGED
@@ -5,16 +5,31 @@
5
5
  * transporte.
6
6
  *
7
7
  * Rotas:
8
- * POST/GET/DELETE /mcp — Streamable HTTP, STATELESS: McpServer e transporte
9
- * novos por request (sessionIdGenerator: undefined),
10
- * o modelo que o SDK recomenda para servidores
11
- * "API-style"/multi-instância. Resposta em SSE
12
- * (default do SDK): a série de 34 anos leva ~30 s e a
8
+ * POST/GET/DELETE /mcp — Streamable HTTP pelo `createMcpHandler` do SDK,
9
+ * adaptado ao node:http por `toNodeHandler`: serve
10
+ * as DUAS eras do protocolo — 2026-07-28 (envelope
11
+ * por request, `server/discover`) e 2025 pelo
12
+ * fallback STATELESS (McpServer e transporte novos
13
+ * por request, `sessionIdGenerator: undefined`, o
14
+ * mesmo modelo "API-style" de antes). Resposta em
15
+ * SSE nas duas eras (`responseMode: "sse"`), com
16
+ * keepalive: a série de 34 anos leva ~30 s e a
13
17
  * conexão precisa ficar viva pelo proxy.
14
18
  * GET /healthz — 200 com versão e anos em cache; NÃO abre o DuckDB
15
19
  * nem baixa nada (é o que o Worker sonda antes de
16
20
  * encaminhar).
17
21
  *
22
+ * POR QUE `createMcpHandler`, E NÃO `server.connect(transport)` + `handleRequest`.
23
+ * Até 25/09/2026 era o segundo — o caminho LEGADO do SDK: só a era 2025, sem
24
+ * `server/discover`, e o cabeçalho MCP-Protocol-Version: 2026-07-28 voltava
25
+ * HTTP 400 "Unsupported protocol version". O mcpscore lia isso como
26
+ * `modern_lifecycle_support: false` e reprovava `protocol_version_latest`
27
+ * (MEDIUM, 2 dos 4 pontos que faltavam para 76/76). A entrada dual-era é a
28
+ * mesma dos seis irmãos em Worker (`createMcpHandler` direto) e a mesma do
29
+ * stdio deste pacote (`serveStdio`, que já era dual-era). O contêiner continua
30
+ * sem validar Host/Origin — a entrada é "deliberately validation-free", e o
31
+ * Worker é o único que fala com ele.
32
+ *
18
33
  * O que NÃO fica aqui, de propósito: validação de Origin/Host, rate limit,
19
34
  * bearer, Analytics Engine — tudo no Worker de borda, que é o único que fala
20
35
  * com este processo (as opções allowedHosts/allowedOrigins do SDK estão
@@ -24,9 +39,11 @@
24
39
  * (SIH_CACHE_DIR, SIH_DATA_DIR, SIH_CUBES_BASE_URL, SIH_FRESHNESS_CHECK...).
25
40
  */
26
41
  import { createServer as createHttpServer } from "node:http";
27
- import { NodeStreamableHTTPServerTransport } from "@modelcontextprotocol/node";
42
+ import { toNodeHandler } from "@modelcontextprotocol/node";
43
+ import { createMcpHandler } from "@modelcontextprotocol/server";
28
44
  import { closeDatabase, getAvailableYears } from "./db/duckdb.js";
29
45
  import { startFreshnessCheck } from "./freshness.js";
46
+ import { unknownCursorErrorFromText } from "./pagination.js";
30
47
  import { SERVER_VERSION } from "./provenance.js";
31
48
  import { createServer, SERVER_NAME } from "./server.js";
32
49
  const PORT = Number(process.env.PORT ?? 8080);
@@ -36,17 +53,50 @@ function sendJson(res, status, body) {
36
53
  res.writeHead(status, { "content-type": "application/json" });
37
54
  res.end(JSON.stringify(body));
38
55
  }
56
+ // UM handler por processo, UMA instância de servidor por request (a factory
57
+ // é chamada a cada exchange, nas duas eras). O handler fecha o que abre.
58
+ const mcpHandler = createMcpHandler(() => createServer(), {
59
+ legacy: "stateless",
60
+ responseMode: "sse",
61
+ onerror: (error) => console.error("[http] erro do handler MCP:", error),
62
+ });
63
+ const serveMcp = toNodeHandler(mcpHandler, {
64
+ onerror: (error) => console.error("[http] erro no adaptador node:", error),
65
+ });
66
+ /**
67
+ * Um `IncomingMessage` já lido, reapresentado ao adaptador do SDK como o
68
+ * mínimo que ele consome (método, URL, cabeçalhos e o corpo como iterável).
69
+ * O guarda de cursor precisa do corpo ANTES do handler, e o stream do Node só
70
+ * se lê uma vez.
71
+ */
72
+ function reapresentado(req, corpo) {
73
+ return {
74
+ method: req.method,
75
+ url: req.url,
76
+ headers: req.headers,
77
+ async *[Symbol.asyncIterator]() {
78
+ yield corpo;
79
+ },
80
+ };
81
+ }
39
82
  async function handleMcp(req, res) {
40
- const server = createServer();
41
- const transport = new NodeStreamableHTTPServerTransport({ sessionIdGenerator: undefined });
42
- // Fecha os dois quando a resposta termina (ou o cliente desiste): sem isso
43
- // cada request deixaria um par servidor/transporte vivo até o GC.
44
- res.on("close", () => {
45
- void transport.close();
46
- void server.close();
47
- });
48
- await server.connect(transport);
49
- await transport.handleRequest(req, res);
83
+ if (req.method !== "POST") {
84
+ await serveMcp(req, res);
85
+ return;
86
+ }
87
+ const pedacos = [];
88
+ for await (const pedaco of req)
89
+ pedacos.push(Buffer.isBuffer(pedaco) ? pedaco : Buffer.from(String(pedaco)));
90
+ const corpo = Buffer.concat(pedacos);
91
+ // Cursor de paginação inválido → -32602 (src/pagination.ts), a mesma recusa
92
+ // do stdio. 200 com o erro JSON-RPC no corpo: a falha é de protocolo, não de
93
+ // HTTP — é assim que o cliente MCP lê o código.
94
+ const recusa = unknownCursorErrorFromText(corpo.toString("utf8"));
95
+ if (recusa) {
96
+ sendJson(res, 200, recusa);
97
+ return;
98
+ }
99
+ await serveMcp(reapresentado(req, corpo), res);
50
100
  }
51
101
  const httpServer = createHttpServer((req, res) => {
52
102
  const url = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
@@ -87,6 +137,7 @@ async function shutdown(signal) {
87
137
  // consider calling start()" em toda chamada). Medido em 09/09/2026.
88
138
  setTimeout(() => process.exit(0), 5_000).unref();
89
139
  httpServer.close();
140
+ await mcpHandler.close().catch(() => undefined);
90
141
  await closeDatabase();
91
142
  process.exit(0);
92
143
  }
package/dist/http.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -5,14 +5,38 @@
5
5
  * A construção do servidor vive em src/server.ts (factory sem efeito
6
6
  * colateral); aqui só se liga ao transporte. stdout é o canal do protocolo,
7
7
  * então todo log vai para o stderr. A entrada HTTP é src/http.ts.
8
+ *
9
+ * O transporte é construído À MÃO e entregue ao `serveStdio` pela opção
10
+ * `transport`, em vez de deixá-lo construir o dele: é a única forma de pôr o
11
+ * guarda de cursor (src/pagination.ts) na frente do `onmessage` SEM abrir mão
12
+ * do `serveStdio` — que é quem atende as duas eras do protocolo (2025 por
13
+ * `initialize`, 2026-07-28 por `server/discover`). `server.connect(transport)`
14
+ * direto atenderia só o ciclo legado e mediria menos regras no mcpscore
15
+ * (armadilha medida no senado em 30/08/2026: 127/144 contra 146/148).
8
16
  */
9
- import { serveStdio } from "@modelcontextprotocol/server/stdio";
17
+ import { serveStdio, StdioServerTransport } from "@modelcontextprotocol/server/stdio";
10
18
  import { closeDatabase } from "./db/duckdb.js";
11
19
  import { startFreshnessCheck } from "./freshness.js";
20
+ import { unknownCursorError } from "./pagination.js";
12
21
  import { createServer } from "./server.js";
22
+ const transport = new StdioServerTransport();
13
23
  serveStdio(() => createServer(), {
24
+ transport,
14
25
  onerror: (error) => console.error("Transport error:", error),
15
26
  });
27
+ // Cursor de paginação inválido → -32602, o mesmo guarda que o contêiner aplica
28
+ // no POST (src/pagination.ts). Entra DEPOIS do serveStdio porque é ele que
29
+ // instala o `onmessage` do transporte (síncrono, na própria chamada):
30
+ // envolvê-lo antes só somaria um ouvinte, sem poder de interromper a entrega.
31
+ const entregaAoServidor = transport.onmessage;
32
+ transport.onmessage = (message) => {
33
+ const recusa = unknownCursorError(message);
34
+ if (recusa) {
35
+ void transport.send(recusa);
36
+ return;
37
+ }
38
+ entregaAoServidor?.(message);
39
+ };
16
40
  console.error("SIH-BR-MCP Server iniciado");
17
41
  // Frescor dos cubos: sonda o manifesto do espelho em segundo plano (512
18
42
  // bytes; só baixa os 10 MB se o manifesto mudou), com timeout curto. Não
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;GAMG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAC;AAEhE,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,UAAU,CAAC,GAAG,EAAE,CAAC,YAAY,EAAE,EAAE;IAC/B,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,kBAAkB,EAAE,KAAK,CAAC;CAC7D,CAAC,CAAC;AACH,OAAO,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;AAE5C,wEAAwE;AACxE,yEAAyE;AACzE,yEAAyE;AACzE,KAAK,mBAAmB,EAAE,CAAC;AAE3B,sBAAsB;AACtB,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;IAC9B,MAAM,aAAa,EAAE,CAAC;IACtB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;IAC/B,MAAM,aAAa,EAAE,CAAC;IACtB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAEtF,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;AAC7C,UAAU,CAAC,GAAG,EAAE,CAAC,YAAY,EAAE,EAAE;IAC/B,SAAS;IACT,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,kBAAkB,EAAE,KAAK,CAAC;CAC7D,CAAC,CAAC;AAEH,+EAA+E;AAC/E,2EAA2E;AAC3E,sEAAsE;AACtE,8EAA8E;AAC9E,MAAM,iBAAiB,GAAG,SAAS,CAAC,SAAS,CAAC;AAC9C,SAAS,CAAC,SAAS,GAAG,CAAC,OAAO,EAAE,EAAE;IAChC,MAAM,MAAM,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAC3C,IAAI,MAAM,EAAE,CAAC;QACX,KAAK,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC5B,OAAO;IACT,CAAC;IACD,iBAAiB,EAAE,CAAC,OAAO,CAAC,CAAC;AAC/B,CAAC,CAAC;AAEF,OAAO,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;AAE5C,wEAAwE;AACxE,yEAAyE;AACzE,yEAAyE;AACzE,KAAK,mBAAmB,EAAE,CAAC;AAE3B,sBAAsB;AACtB,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;IAC9B,MAAM,aAAa,EAAE,CAAC;IACtB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;IAC/B,MAAM,aAAa,EAAE,CAAC;IACtB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Cursor de paginação inválido — a recusa que o SDK não faz.
3
+ *
4
+ * O PROBLEMA. A única lista deste servidor (`tools/list`, doze ferramentas)
5
+ * cabe numa página só, então nenhuma resposta traz `nextCursor` e nenhum
6
+ * cursor emitido por este servidor existe. O handler de lista do
7
+ * `@modelcontextprotocol/server` 2.0.0 simplesmente IGNORA `params.cursor` e
8
+ * devolve a lista inteira — inclusive para um cursor que o servidor nunca
9
+ * emitiu. A spec (§Pagination, Error Handling, em toda revisão datada) diz que
10
+ * cursor inválido DEVE virar `-32602`, e o `mcpscore` reprovava
11
+ * `pagination_tools_invalid_cursor` nos dois transportes (medido em
12
+ * 25/09/2026: 72/76 em produção, 98/103 no stdio — esta era uma das três
13
+ * regras que faltavam).
14
+ *
15
+ * POR QUE AQUI, E NÃO NO HANDLER DO SDK. Sobrescrever `tools/list` exigiria
16
+ * reimplementar a listagem a partir do registro privado do McpServer
17
+ * (`_registeredTools`, com a conversão de schema junto) — trocar um defeito
18
+ * pequeno por uma cópia do SDK que envelhece sozinha. A recusa é uma decisão
19
+ * sobre a MENSAGEM, não sobre o conteúdo da lista, então mora na borda por onde
20
+ * a mensagem entra: o `onmessage` do transporte stdio (src/index.ts) e o POST
21
+ * do contêiner (src/http.ts). O predicado é o mesmo nos dois — este módulo,
22
+ * transplantado do ilo-mcp-server (a implementação de referência do portfólio,
23
+ * 182/182 com o mesmo SDK).
24
+ *
25
+ * NO CONTÊINER, E NÃO NO WORKER DE BORDA. O Worker (worker/src/index.ts) já lê
26
+ * uma cópia do corpo para a telemetria e poderia recusar ali — mas o
27
+ * `smoke:http` e o mcpscore `--stdio` medem o contêiner e o pacote SEM o
28
+ * Worker, e uma recusa que só existe na borda deixaria os dois canais medidos
29
+ * diferentes do que o usuário do domínio recebe.
30
+ *
31
+ * ENQUANTO NÃO HOUVER SEGUNDA PÁGINA. Se algum dia uma lista passar a paginar
32
+ * de verdade, este módulo deixa de valer: a recusa passa a ser "cursor que não
33
+ * decodifica", e quem emite o cursor é quem sabe reconhecê-lo. O teste
34
+ * tests/pagination.test.ts prende a premissa (nenhuma lista emite nextCursor)
35
+ * para que a mudança não passe em silêncio.
36
+ */
37
+ /** Código JSON-RPC de parâmetro inválido (spec §Pagination, Error Handling). */
38
+ export declare const INVALID_PARAMS = -32602;
39
+ /**
40
+ * Os quatro métodos de lista paginável do MCP. O sih só serve `tools/list`
41
+ * (sem resources nem prompts), mas o guarda cobre os quatro: um cliente que
42
+ * pergunte `resources/list` com cursor recebe a recusa certa em vez de cair no
43
+ * "método não encontrado" do SDK — e se um dia entrarem resources ou prompts,
44
+ * a recusa já os cobre.
45
+ */
46
+ export declare const PAGINATED_LIST_METHODS: readonly ["tools/list", "resources/list", "resources/templates/list", "prompts/list"];
47
+ /** Resposta de erro JSON-RPC — a forma que os dois transportes enviam. */
48
+ export interface JsonRpcErrorResponse {
49
+ jsonrpc: "2.0";
50
+ id: string | number;
51
+ error: {
52
+ code: number;
53
+ message: string;
54
+ };
55
+ }
56
+ /**
57
+ * Devolve a recusa `-32602` quando a mensagem é uma requisição de lista que
58
+ * carrega `cursor`; `undefined` em qualquer outro caso (inclusive notificação,
59
+ * lote e mensagem malformada — nenhum deles é assunto deste guarda, e o SDK
60
+ * responde por eles).
61
+ */
62
+ export declare function unknownCursorError(message: unknown): JsonRpcErrorResponse | undefined;
63
+ /**
64
+ * Adaptador da borda HTTP do contêiner: recebe o corpo do POST já lido como
65
+ * texto e decide. Corpo que não é JSON não é assunto daqui — o handler do SDK
66
+ * dá o erro dele (-32700), e por isso o texto cru é devolvido intacto ao
67
+ * handler por quem chama (src/http.ts), nunca reinterpretado aqui.
68
+ */
69
+ export declare function unknownCursorErrorFromText(text: string): JsonRpcErrorResponse | undefined;
70
+ //# sourceMappingURL=pagination.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../src/pagination.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,gFAAgF;AAChF,eAAO,MAAM,cAAc,SAAS,CAAC;AAErC;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,YACjC,YAAY,EACZ,gBAAgB,EAChB,0BAA0B,EAC1B,cAAc,CACN,CAAC;AAEX,0EAA0E;AAC1E,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,KAAK,CAAC;IACf,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAC1C;AASD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,oBAAoB,GAAG,SAAS,CAqBrF;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,oBAAoB,GAAG,SAAS,CAQzF"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Cursor de paginação inválido — a recusa que o SDK não faz.
3
+ *
4
+ * O PROBLEMA. A única lista deste servidor (`tools/list`, doze ferramentas)
5
+ * cabe numa página só, então nenhuma resposta traz `nextCursor` e nenhum
6
+ * cursor emitido por este servidor existe. O handler de lista do
7
+ * `@modelcontextprotocol/server` 2.0.0 simplesmente IGNORA `params.cursor` e
8
+ * devolve a lista inteira — inclusive para um cursor que o servidor nunca
9
+ * emitiu. A spec (§Pagination, Error Handling, em toda revisão datada) diz que
10
+ * cursor inválido DEVE virar `-32602`, e o `mcpscore` reprovava
11
+ * `pagination_tools_invalid_cursor` nos dois transportes (medido em
12
+ * 25/09/2026: 72/76 em produção, 98/103 no stdio — esta era uma das três
13
+ * regras que faltavam).
14
+ *
15
+ * POR QUE AQUI, E NÃO NO HANDLER DO SDK. Sobrescrever `tools/list` exigiria
16
+ * reimplementar a listagem a partir do registro privado do McpServer
17
+ * (`_registeredTools`, com a conversão de schema junto) — trocar um defeito
18
+ * pequeno por uma cópia do SDK que envelhece sozinha. A recusa é uma decisão
19
+ * sobre a MENSAGEM, não sobre o conteúdo da lista, então mora na borda por onde
20
+ * a mensagem entra: o `onmessage` do transporte stdio (src/index.ts) e o POST
21
+ * do contêiner (src/http.ts). O predicado é o mesmo nos dois — este módulo,
22
+ * transplantado do ilo-mcp-server (a implementação de referência do portfólio,
23
+ * 182/182 com o mesmo SDK).
24
+ *
25
+ * NO CONTÊINER, E NÃO NO WORKER DE BORDA. O Worker (worker/src/index.ts) já lê
26
+ * uma cópia do corpo para a telemetria e poderia recusar ali — mas o
27
+ * `smoke:http` e o mcpscore `--stdio` medem o contêiner e o pacote SEM o
28
+ * Worker, e uma recusa que só existe na borda deixaria os dois canais medidos
29
+ * diferentes do que o usuário do domínio recebe.
30
+ *
31
+ * ENQUANTO NÃO HOUVER SEGUNDA PÁGINA. Se algum dia uma lista passar a paginar
32
+ * de verdade, este módulo deixa de valer: a recusa passa a ser "cursor que não
33
+ * decodifica", e quem emite o cursor é quem sabe reconhecê-lo. O teste
34
+ * tests/pagination.test.ts prende a premissa (nenhuma lista emite nextCursor)
35
+ * para que a mudança não passe em silêncio.
36
+ */
37
+ /** Código JSON-RPC de parâmetro inválido (spec §Pagination, Error Handling). */
38
+ export const INVALID_PARAMS = -32602;
39
+ /**
40
+ * Os quatro métodos de lista paginável do MCP. O sih só serve `tools/list`
41
+ * (sem resources nem prompts), mas o guarda cobre os quatro: um cliente que
42
+ * pergunte `resources/list` com cursor recebe a recusa certa em vez de cair no
43
+ * "método não encontrado" do SDK — e se um dia entrarem resources ou prompts,
44
+ * a recusa já os cobre.
45
+ */
46
+ export const PAGINATED_LIST_METHODS = [
47
+ "tools/list",
48
+ "resources/list",
49
+ "resources/templates/list",
50
+ "prompts/list",
51
+ ];
52
+ /**
53
+ * Devolve a recusa `-32602` quando a mensagem é uma requisição de lista que
54
+ * carrega `cursor`; `undefined` em qualquer outro caso (inclusive notificação,
55
+ * lote e mensagem malformada — nenhum deles é assunto deste guarda, e o SDK
56
+ * responde por eles).
57
+ */
58
+ export function unknownCursorError(message) {
59
+ if (typeof message !== "object" || message === null || Array.isArray(message))
60
+ return undefined;
61
+ const { jsonrpc, id, method, params } = message;
62
+ if (jsonrpc !== "2.0")
63
+ return undefined;
64
+ // Sem id é notificação: não existe resposta para devolver.
65
+ if (typeof id !== "string" && typeof id !== "number")
66
+ return undefined;
67
+ if (typeof method !== "string")
68
+ return undefined;
69
+ if (!PAGINATED_LIST_METHODS.includes(method))
70
+ return undefined;
71
+ if (params === null || typeof params !== "object" || params.cursor === undefined)
72
+ return undefined;
73
+ return {
74
+ jsonrpc: "2.0",
75
+ id,
76
+ error: {
77
+ code: INVALID_PARAMS,
78
+ message: `Invalid params: unknown pagination cursor for ${method}. ` +
79
+ "This server returns every list in a single page and never issues a nextCursor, " +
80
+ "so no cursor value is valid — retry without one.",
81
+ },
82
+ };
83
+ }
84
+ /**
85
+ * Adaptador da borda HTTP do contêiner: recebe o corpo do POST já lido como
86
+ * texto e decide. Corpo que não é JSON não é assunto daqui — o handler do SDK
87
+ * dá o erro dele (-32700), e por isso o texto cru é devolvido intacto ao
88
+ * handler por quem chama (src/http.ts), nunca reinterpretado aqui.
89
+ */
90
+ export function unknownCursorErrorFromText(text) {
91
+ let corpo;
92
+ try {
93
+ corpo = JSON.parse(text);
94
+ }
95
+ catch {
96
+ return undefined;
97
+ }
98
+ return unknownCursorError(corpo);
99
+ }
100
+ //# sourceMappingURL=pagination.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pagination.js","sourceRoot":"","sources":["../src/pagination.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,gFAAgF;AAChF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,KAAK,CAAC;AAErC;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,YAAY;IACZ,gBAAgB;IAChB,0BAA0B;IAC1B,cAAc;CACN,CAAC;AAgBX;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAgB;IACjD,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;QAAE,OAAO,SAAS,CAAC;IAChG,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,OAA6B,CAAC;IACtE,IAAI,OAAO,KAAK,KAAK;QAAE,OAAO,SAAS,CAAC;IACxC,2DAA2D;IAC3D,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,OAAO,EAAE,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IACvE,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IACjD,IAAI,CAAE,sBAA4C,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,SAAS,CAAC;IACtF,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAEnG,OAAO;QACL,OAAO,EAAE,KAAK;QACd,EAAE;QACF,KAAK,EAAE;YACL,IAAI,EAAE,cAAc;YACpB,OAAO,EACL,iDAAiD,MAAM,IAAI;gBAC3D,iFAAiF;gBACjF,kDAAkD;SACrD;KACF,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,0BAA0B,CAAC,IAAY;IACrD,IAAI,KAAc,CAAC;IACnB,IAAI,CAAC;QACH,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,kBAAkB,CAAC,KAAK,CAAC,CAAC;AACnC,CAAC"}
package/dist/server.d.ts CHANGED
@@ -15,6 +15,20 @@
15
15
  */
16
16
  import { McpServer } from "@modelcontextprotocol/server";
17
17
  export declare const SERVER_NAME = "sih-br-mcp";
18
+ export declare const SERVER_WEBSITE_URL = "https://sih.sidneybissoli.com";
18
19
  export declare const SERVER_TITLE = "DATASUS SIH/SUS \u2014 Brazil Hospital Admissions (AIH) MCP";
20
+ /**
21
+ * Instruções do handshake MCP (`initialize.result.instructions`): o que o
22
+ * servidor cobre, o fluxo típico entre as doze ferramentas e quando o cliente
23
+ * NÃO deve usá-lo (critério de review de conectores da Anthropic; regra
24
+ * `server_instructions_present` do mcpscore, reprovada até 25/09/2026). Em
25
+ * inglês, como o título e o server.json — é o texto que o modelo lê, e o
26
+ * vocabulário da pergunta em inglês ("hospital admissions", "ICD-10", "AIH") é
27
+ * o que a ação GEO de 13/09/2026 fixou para as superfícies públicas. As doze
28
+ * ferramentas são citadas pelo nome, e tests/instructions.test.ts prende os
29
+ * dois lados: todo nome citado existe, e toda ferramenta é citada — uma
30
+ * ferramenta nova sem lugar no fluxo reprova ali, não no chat.
31
+ */
32
+ export declare const SERVER_INSTRUCTIONS: string;
19
33
  export declare function createServer(): McpServer;
20
34
  //# sourceMappingURL=server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EACL,SAAS,EAOV,MAAM,8BAA8B,CAAC;AAMtC,eAAO,MAAM,WAAW,eAAe,CAAC;AASxC,eAAO,MAAM,YAAY,gEAA2D,CAAC;AAiDrF,wBAAgB,YAAY,IAAI,SAAS,CAmBxC"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EACL,SAAS,EAOV,MAAM,8BAA8B,CAAC;AAOtC,eAAO,MAAM,WAAW,eAAe,CAAC;AACxC,eAAO,MAAM,kBAAkB,kCAAkC,CAAC;AASlE,eAAO,MAAM,YAAY,gEAA2D,CAAC;AAErF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB,QAe8B,CAAC;AAiD/D,wBAAgB,YAAY,IAAI,SAAS,CAmCxC"}
package/dist/server.js CHANGED
@@ -15,9 +15,11 @@
15
15
  */
16
16
  import { McpServer, fromJsonSchema, } from "@modelcontextprotocol/server";
17
17
  import { CfWorkerJsonSchemaValidator } from "@modelcontextprotocol/server/validators/cf-worker";
18
+ import { announceServedVersions } from "./discover.js";
18
19
  import { SERVER_VERSION } from "./provenance.js";
19
20
  import { callTool, tools } from "./tools.js";
20
21
  export const SERVER_NAME = "sih-br-mcp";
22
+ export const SERVER_WEBSITE_URL = "https://sih.sidneybissoli.com";
21
23
  // O título canônico do produto, e ele mora em TRÊS superfícies que têm de
22
24
  // concordar: este SERVER_TITLE (o que o cliente MCP mostra no handshake), o
23
25
  // `title` do server.json (o que o registro oficial e os diretórios exibem) e o
@@ -27,6 +29,33 @@ export const SERVER_NAME = "sih-br-mcp";
27
29
  // diretório outro. Passou despercebido por um dia porque os testes do worker,
28
30
  // que comparam os três, não rodavam no CI (corrigido em 14/09).
29
31
  export const SERVER_TITLE = "DATASUS SIH/SUS — Brazil Hospital Admissions (AIH) MCP";
32
+ /**
33
+ * Instruções do handshake MCP (`initialize.result.instructions`): o que o
34
+ * servidor cobre, o fluxo típico entre as doze ferramentas e quando o cliente
35
+ * NÃO deve usá-lo (critério de review de conectores da Anthropic; regra
36
+ * `server_instructions_present` do mcpscore, reprovada até 25/09/2026). Em
37
+ * inglês, como o título e o server.json — é o texto que o modelo lê, e o
38
+ * vocabulário da pergunta em inglês ("hospital admissions", "ICD-10", "AIH") é
39
+ * o que a ação GEO de 13/09/2026 fixou para as superfícies públicas. As doze
40
+ * ferramentas são citadas pelo nome, e tests/instructions.test.ts prende os
41
+ * dois lados: todo nome citado existe, e toda ferramenta é citada — uma
42
+ * ferramenta nova sem lugar no fluxo reprova ali, não no chat.
43
+ */
44
+ export const SERVER_INSTRUCTIONS = "Brazilian hospital admissions from DATASUS SIH/SUS (AIH records, 1992-2025), read from " +
45
+ "pre-aggregated public cubes of the healthbr-data Parquet mirror, never from the FTP or " +
46
+ "TabNet: causes by ICD-10 chapter and group (ICD-9 before 1998), monthly series, ambulatory " +
47
+ "care sensitive conditions (ICSAP, the Brazilian list) and crude, age-specific or " +
48
+ "age-standardized rates per 100,000 by state and municipality. Every stratum carries " +
49
+ "admissions, length of stay, amount paid by SUS and deaths; every response carries a " +
50
+ "provenance block with the data vintage and the citation. Typical flow: get_available_years " +
51
+ "first (which years each cube covers), then get_hospitalizations for counts by cause, place, " +
52
+ "age, sex and race, get_hospitalization_trends for monthly or annual series, " +
53
+ "get_hospitalization_rates and compare_regions for rates; get_icsap, get_icsap_indicators, " +
54
+ "rank_csap_groups and compare_icsap_trends for ICSAP; list_cid_chapters, list_csap_groups and " +
55
+ "classify_as_csap resolve codes and groups before querying. Do not use this server for " +
56
+ "individual AIH records, for variables the cubes do not carry (procedure performed, facility " +
57
+ "CNES, secondary diagnosis) or for other DATASUS systems (SIM, SINASC, SIA, SINAN): use " +
58
+ "microdatasus, PySUS or the healthbr-data mirror for those.";
30
59
  // Review de conectores do claude.ai (claude.com/docs/connectors/building/
31
60
  // review-criteria, lido em 08/09/2026): toda ferramenta com `title` e
32
61
  // `readOnlyHint`. As doze só leem: cubos agregados e população, do disco ou
@@ -72,7 +101,21 @@ const validadorPermissivo = {
72
101
  },
73
102
  };
74
103
  export function createServer() {
75
- const server = new McpServer({ name: SERVER_NAME, version: SERVER_VERSION, title: SERVER_TITLE }, { capabilities: { tools: {} } });
104
+ const server = new McpServer({
105
+ name: SERVER_NAME,
106
+ version: SERVER_VERSION,
107
+ title: SERVER_TITLE,
108
+ // O site e o ícone no handshake (campos da revisão 2025-11-25). As
109
+ // MESMAS URLs do server.json: worker/tests/icon.test.ts prende os três
110
+ // lugares (bytes no Worker, serverInfo aqui, manifesto no registro)
111
+ // para o handshake e os diretórios nunca mostrarem imagens diferentes.
112
+ websiteUrl: SERVER_WEBSITE_URL,
113
+ icons: [{ src: `${SERVER_WEBSITE_URL}/icon.png`, mimeType: "image/png", sizes: ["512x512"] }],
114
+ }, { capabilities: { tools: {} }, instructions: SERVER_INSTRUCTIONS });
115
+ // server/discover anuncia todas as revisões atendidas, não só as modernas —
116
+ // ver src/discover.ts. Antes das tools: se o SDK mudar por baixo, o servidor
117
+ // falha ao construir e não meio-construído.
118
+ announceServedVersions(server);
76
119
  for (const tool of tools) {
77
120
  server.registerTool(tool.name, {
78
121
  title: tool.title,
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EACL,SAAS,EACT,cAAc,GAMf,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,2BAA2B,EAAE,MAAM,mDAAmD,CAAC;AAEhG,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAiB,MAAM,YAAY,CAAC;AAE5D,MAAM,CAAC,MAAM,WAAW,GAAG,YAAY,CAAC;AACxC,0EAA0E;AAC1E,4EAA4E;AAC5E,+EAA+E;AAC/E,wEAAwE;AACxE,6EAA6E;AAC7E,yEAAyE;AACzE,8EAA8E;AAC9E,gEAAgE;AAChE,MAAM,CAAC,MAAM,YAAY,GAAG,wDAAwD,CAAC;AAErF,0EAA0E;AAC1E,sEAAsE;AACtE,4EAA4E;AAC5E,2EAA2E;AAC3E,2EAA2E;AAC3E,4EAA4E;AAC5E,gCAAgC;AAChC,MAAM,SAAS,GAAoB;IACjC,YAAY,EAAE,IAAI;IAClB,eAAe,EAAE,KAAK;IACtB,cAAc,EAAE,IAAI;IACpB,aAAa,EAAE,KAAK;CACrB,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,kBAAkB,GAAG,IAAI,2BAA2B,EAAE,CAAC;AAE7D;;;;;;;GAOG;AACH,MAAM,mBAAmB,GAAwB;IAC/C,YAAY;QACV,OAAO,CAAC,KAAc,EAAgC,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAU,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC,CAAC;IACxH,CAAC;CACF,CAAC;AAEF,MAAM,UAAU,YAAY;IAC1B,MAAM,MAAM,GAAG,IAAI,SAAS,CAC1B,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,EAAE,EACnE,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,CAChC,CAAC;IACF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,CAAC,YAAY,CACjB,IAAI,CAAC,IAAI,EACT;YACE,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,WAAW,EAAE,cAAc,CAAW,IAAI,CAAC,WAA6B,EAAE,kBAAkB,CAAC;YAC7F,YAAY,EAAE,cAAc,CAAC,IAAI,CAAC,YAA8B,EAAE,mBAAmB,CAAC;YACtF,WAAW,EAAE,SAAS;SACvB,EACD,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CACpC,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sih-br-mcp",
3
- "version": "0.18.0",
3
+ "version": "1.0.1",
4
4
  "mcpName": "io.github.SidneyBissoli/sih-br-mcp",
5
5
  "description": "Servidor MCP do DATASUS SIH/SUS: internações hospitalares do Brasil (AIH, 1992–2025) — causas CID-10 e CID-9, séries mensais, ICSAP e taxas por UF e município, sem baixar .dbc nem usar TabNet. Brazilian hospital admissions (SIH/SUS) MCP server.",
6
6
  "repository": {