@sbissoli/mcp-surface 0.1.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/CHANGELOG.md +29 -0
- package/README.md +79 -0
- package/dist/cli.d.ts +23 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +101 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/memoria.d.ts +15 -0
- package/dist/memoria.d.ts.map +1 -0
- package/dist/memoria.js +40 -0
- package/dist/memoria.js.map +1 -0
- package/dist/remoto.d.ts +17 -0
- package/dist/remoto.d.ts.map +1 -0
- package/dist/remoto.js +65 -0
- package/dist/remoto.js.map +1 -0
- package/dist/replay.d.ts +48 -0
- package/dist/replay.d.ts.map +1 -0
- package/dist/replay.js +220 -0
- package/dist/replay.js.map +1 -0
- package/dist/sonda.d.ts +53 -0
- package/dist/sonda.d.ts.map +1 -0
- package/dist/sonda.js +105 -0
- package/dist/sonda.js.map +1 -0
- package/dist/superficie.d.ts +47 -0
- package/dist/superficie.d.ts.map +1 -0
- package/dist/superficie.js +89 -0
- package/dist/superficie.js.map +1 -0
- package/dist/trava.d.ts +38 -0
- package/dist/trava.d.ts.map +1 -0
- package/dist/trava.js +75 -0
- package/dist/trava.js.map +1 -0
- package/dist/verificar.d.ts +21 -0
- package/dist/verificar.d.ts.map +1 -0
- package/dist/verificar.js +47 -0
- package/dist/verificar.js.map +1 -0
- package/package.json +52 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Changelog — @sbissoli/mcp-surface
|
|
2
|
+
|
|
3
|
+
Formato: [Keep a Changelog](https://keepachangelog.com/pt-BR/1.1.0/). Versões seguem
|
|
4
|
+
semver; em 0.x, superfície publicada que muda é minor (caret `^0.x` não cobre o minor
|
|
5
|
+
seguinte — cada servidor faz bump explícito).
|
|
6
|
+
|
|
7
|
+
**Mudar a normalização muda o sha256 de todo `surface.lock.json` que usa o pacote** —
|
|
8
|
+
e, pela regra da trava, obrigaria cada servidor a subir de versão sem ter mudado nada.
|
|
9
|
+
Mudança de normalização é major (ou minor em 0.x), com nota de migração.
|
|
10
|
+
|
|
11
|
+
## [0.1.0] — 2026-10-02
|
|
12
|
+
|
|
13
|
+
Primeira versão, extraída do molde no bcb-br-mcp (PR #49, 1.15.1). A normalização é a do
|
|
14
|
+
bcb byte a byte: o `surface.lock.json` travado lá confere com este pacote
|
|
15
|
+
(`mcp-surface verificar https://bcb.sidneybissoli.com/mcp` → `1d31ec423d36`).
|
|
16
|
+
|
|
17
|
+
### Adicionado
|
|
18
|
+
|
|
19
|
+
- `capturarSuperficie(server)` — superfície em memória (`InMemoryTransport` do SDK v2,
|
|
20
|
+
JSON-RPC cru): `initialize` (instructions, capabilities, `serverInfo` sem a versão) +
|
|
21
|
+
`tools/list` + `resources/list` + `resources/templates/list` + `prompts/list`.
|
|
22
|
+
`normalizarSuperficie` e `impressaoDigital` (sha256 do JSON canônico).
|
|
23
|
+
- `conferirSecao(trava, "declarada" | "semToken", medido, versao)` — a regra: divergiu sob a
|
|
24
|
+
mesma versão = falha, inclusive em modo de escrita; o sha gravado denuncia edição à mão.
|
|
25
|
+
- `sondaSemToken`, `medirSemToken`, `comHost`, `ipDaSonda` — quem responde sem credencial,
|
|
26
|
+
medido na borda HTTP de cada servidor.
|
|
27
|
+
- CLI `mcp-surface`: `travar` (regrava rodando os testes em modo de escrita), `verificar`
|
|
28
|
+
(endpoint no ar contra a trava, com repetição para a propagação da Cloudflare) e `replay`
|
|
29
|
+
(todas as versões publicadas no npm, uma contra a anterior, e o ar contra o `/status`).
|
package/README.md
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# @sbissoli/mcp-surface
|
|
2
|
+
|
|
3
|
+
**Mudou a superfície sem subir a versão = build vermelho e deploy recusado.**
|
|
4
|
+
|
|
5
|
+
> Mantido para o meu portfólio de servidores MCP. Uso por terceiros é bem-vindo, mas o
|
|
6
|
+
> roadmap segue as necessidades dos meus servidores.
|
|
7
|
+
|
|
8
|
+
A cópia de um servidor no MCP Registry carrega só nome, versão, pacotes e remotos — nenhuma
|
|
9
|
+
superfície. Quem compara o registro com o servidor só consegue comparar a **versão**, e isso
|
|
10
|
+
só vale se toda mudança de superfície subir a versão. Este pacote transforma essa disciplina
|
|
11
|
+
em teste. A ideia veio de um leitor (dev.to,
|
|
12
|
+
[3g5m4](https://dev.to/yahhi/comment/3g5m4) e 3g607), que achou o caso grave no servidor
|
|
13
|
+
dele: registro dizendo 0.1.0 com 4 tools só-leitura, servidor com 6, duas escrevendo pelo
|
|
14
|
+
usuário.
|
|
15
|
+
|
|
16
|
+
## O que entra na impressão digital
|
|
17
|
+
|
|
18
|
+
O `surface.lock.json`, commitado na raiz do servidor, tem duas seções. Cada uma guarda a
|
|
19
|
+
versão do `package.json` em que foi travada e o sha256 do conteúdo:
|
|
20
|
+
|
|
21
|
+
- **`declarada`** — `initialize` (instructions, capabilities, `serverInfo` sem a versão) +
|
|
22
|
+
`tools/list` + `resources/list` + `resources/templates/list` + `prompts/list`,
|
|
23
|
+
normalizados (chaves ordenadas, listas por nome/uri). Método não servido é `null`, não `[]`.
|
|
24
|
+
- **`semToken`** — QUAIS MÉTODOS RESPONDEM SEM CREDENCIAL, por configuração (ex.: `API_KEY`
|
|
25
|
+
ausente e presente) e por rota. É comportamento que nenhuma listagem mostra.
|
|
26
|
+
|
|
27
|
+
A regra (`conferirSecao`): medido ≠ travado e versão igual → **falha**; versão diferente →
|
|
28
|
+
falha pedindo `npm run surface:lock`. O modo de escrita obedece à mesma regra e recusa
|
|
29
|
+
travar superfície nova sob a versão antiga.
|
|
30
|
+
|
|
31
|
+
## Adoção num servidor
|
|
32
|
+
|
|
33
|
+
1. **Teste da superfície declarada** (onde a fábrica do servidor é importável):
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
import { capturarSuperficie, conferirSecao } from "@sbissoli/mcp-surface";
|
|
37
|
+
import { createServer } from "../src/server.js";
|
|
38
|
+
|
|
39
|
+
it("surface.lock.json — superfície declarada", async () => {
|
|
40
|
+
const v = conferirSecao("surface.lock.json", "declarada", await capturarSuperficie(createServer()), pkg.version);
|
|
41
|
+
expect(v.ok, v.mensagem).toBe(true);
|
|
42
|
+
});
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
2. **Teste de quem responde sem token** (na borda HTTP, chamando o `fetch` do Worker):
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
import { comHost, conferirSecao, corpoDoPedido, CABECALHOS_MCP, ipDaSonda, medirSemToken, sondaSemToken } from "@sbissoli/mcp-surface";
|
|
49
|
+
|
|
50
|
+
const envs = { apiKeyAusente: {} as Env, apiKeyPresente: { API_KEY: "x" } as Env };
|
|
51
|
+
const medido = await medirSemToken(Object.keys(envs), ["POST /mcp", "POST /mcp/uso-proprio"],
|
|
52
|
+
sondaSemToken({ name: "<tool sem rede>", arguments: {} }),
|
|
53
|
+
(config, rota, pedido) => worker.fetch(comHost(new Request(`https://host${rota.slice(5)}`, {
|
|
54
|
+
method: "POST", headers: { ...CABECALHOS_MCP, "CF-Connecting-IP": ipDaSonda() }, body: corpoDoPedido(pedido),
|
|
55
|
+
}), "host"), envs[config], ctx));
|
|
56
|
+
expect(conferirSecao("surface.lock.json", "semToken", medido, pkg.version).ok).toBe(true);
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
3. **Script** no `package.json`:
|
|
60
|
+
`"surface:lock": "npm run build && mcp-surface travar --cmd \"vitest run tests/surface-lock.test.ts\""`.
|
|
61
|
+
|
|
62
|
+
4. **Deploy**: rodar `npm test` ANTES do wrangler, e no fim
|
|
63
|
+
`npx mcp-surface verificar https://<host>/mcp --tool <tool sem rede>` — prova que o que
|
|
64
|
+
está no ar é o que foi travado. **Publish**: `npm test` antes do npm.
|
|
65
|
+
|
|
66
|
+
5. **Uma vez**: `npx mcp-surface replay --url https://<host>/mcp` grava
|
|
67
|
+
`baselines/replay-<data>.md` com todas as versões publicadas no npm, uma contra a
|
|
68
|
+
anterior, as remoções fora de major e o ar contra a versão que o `/status` declara.
|
|
69
|
+
|
|
70
|
+
Fluxo de quem muda a superfície: `npm version <nível> --no-git-tag-version` →
|
|
71
|
+
`npm run surface:lock` → commitar o lock junto.
|
|
72
|
+
|
|
73
|
+
## Observações
|
|
74
|
+
|
|
75
|
+
- Uma atualização do SDK que mexa nas `capabilities` também acende a trava — de propósito:
|
|
76
|
+
o cliente vê outra superfície.
|
|
77
|
+
- Superfície que depende de ambiente (flag de feature, perfil de tools) precisa ser travada
|
|
78
|
+
com o ambiente fixo, ou em uma captura por perfil.
|
|
79
|
+
- Mudar a normalização deste pacote muda o sha de todo lock que o usa — ver o CHANGELOG.
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* mcp-surface — a trava da superfície pela linha de comando.
|
|
4
|
+
*
|
|
5
|
+
* mcp-surface travar --cmd "<comando de teste>" [--cmd ...]
|
|
6
|
+
* Roda cada comando com SURFACE_LOCK_ESCREVER=1: os testes da trava
|
|
7
|
+
* regravam o surface.lock.json — e se recusam se a superfície mudou sem
|
|
8
|
+
* subir a versão. Ex. (npm script):
|
|
9
|
+
* "surface:lock": "npm run build && mcp-surface travar --cmd \"vitest run tests/surface-lock.test.ts\""
|
|
10
|
+
*
|
|
11
|
+
* mcp-surface verificar <endpoint> [--trava surface.lock.json] [--config apiKeyAusente]
|
|
12
|
+
* [--rota "POST /mcp"] [--tool <nome>] [--args '<json>']
|
|
13
|
+
* Confere o endpoint no ar contra a trava (superfície declarada + quem
|
|
14
|
+
* responde sem token). Fim do deploy. Sai com 1 se divergir.
|
|
15
|
+
*
|
|
16
|
+
* mcp-surface replay [--pacote <nome npm>] [--registro <nome no MCP Registry>]
|
|
17
|
+
* [--url <endpoint>] [--saida baselines]
|
|
18
|
+
* Replay retroativo de todas as versões publicadas; escreve
|
|
19
|
+
* <saida>/replay-<data>.md e .json. Padrões lidos do package.json e do
|
|
20
|
+
* server.json do diretório atual.
|
|
21
|
+
*/
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;GAmBG"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* mcp-surface — a trava da superfície pela linha de comando.
|
|
4
|
+
*
|
|
5
|
+
* mcp-surface travar --cmd "<comando de teste>" [--cmd ...]
|
|
6
|
+
* Roda cada comando com SURFACE_LOCK_ESCREVER=1: os testes da trava
|
|
7
|
+
* regravam o surface.lock.json — e se recusam se a superfície mudou sem
|
|
8
|
+
* subir a versão. Ex. (npm script):
|
|
9
|
+
* "surface:lock": "npm run build && mcp-surface travar --cmd \"vitest run tests/surface-lock.test.ts\""
|
|
10
|
+
*
|
|
11
|
+
* mcp-surface verificar <endpoint> [--trava surface.lock.json] [--config apiKeyAusente]
|
|
12
|
+
* [--rota "POST /mcp"] [--tool <nome>] [--args '<json>']
|
|
13
|
+
* Confere o endpoint no ar contra a trava (superfície declarada + quem
|
|
14
|
+
* responde sem token). Fim do deploy. Sai com 1 se divergir.
|
|
15
|
+
*
|
|
16
|
+
* mcp-surface replay [--pacote <nome npm>] [--registro <nome no MCP Registry>]
|
|
17
|
+
* [--url <endpoint>] [--saida baselines]
|
|
18
|
+
* Replay retroativo de todas as versões publicadas; escreve
|
|
19
|
+
* <saida>/replay-<data>.md e .json. Padrões lidos do package.json e do
|
|
20
|
+
* server.json do diretório atual.
|
|
21
|
+
*/
|
|
22
|
+
import { spawnSync } from "node:child_process";
|
|
23
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
24
|
+
import { join } from "node:path";
|
|
25
|
+
import { replay } from "./replay.js";
|
|
26
|
+
import { VAR_ESCRITA } from "./trava.js";
|
|
27
|
+
import { verificarNoAr } from "./verificar.js";
|
|
28
|
+
const [comando, ...resto] = process.argv.slice(2);
|
|
29
|
+
function opcao(nome) {
|
|
30
|
+
const i = resto.indexOf(`--${nome}`);
|
|
31
|
+
return i >= 0 ? resto[i + 1] : undefined;
|
|
32
|
+
}
|
|
33
|
+
function opcoes(nome) {
|
|
34
|
+
return resto.flatMap((a, i) => (a === `--${nome}` && resto[i + 1] ? [resto[i + 1]] : []));
|
|
35
|
+
}
|
|
36
|
+
function lerJson(caminho) {
|
|
37
|
+
return existsSync(caminho) ? JSON.parse(readFileSync(caminho, "utf8")) : undefined;
|
|
38
|
+
}
|
|
39
|
+
async function main() {
|
|
40
|
+
if (comando === "travar") {
|
|
41
|
+
const cmds = opcoes("cmd");
|
|
42
|
+
if (!cmds.length) {
|
|
43
|
+
console.error('uso: mcp-surface travar --cmd "<comando>" [--cmd ...]');
|
|
44
|
+
return 2;
|
|
45
|
+
}
|
|
46
|
+
for (const cmd of cmds) {
|
|
47
|
+
const r = spawnSync(cmd, { shell: true, stdio: "inherit", env: { ...process.env, [VAR_ESCRITA]: "1" } });
|
|
48
|
+
if (r.status !== 0)
|
|
49
|
+
return r.status ?? 1;
|
|
50
|
+
}
|
|
51
|
+
console.log("surface.lock.json em dia — commite-o junto com a versão.");
|
|
52
|
+
return 0;
|
|
53
|
+
}
|
|
54
|
+
if (comando === "verificar") {
|
|
55
|
+
const url = resto[0];
|
|
56
|
+
if (!url || url.startsWith("--")) {
|
|
57
|
+
console.error("uso: mcp-surface verificar <endpoint> [--trava ...] [--config ...] [--rota ...] [--tool ... --args ...]");
|
|
58
|
+
return 2;
|
|
59
|
+
}
|
|
60
|
+
const tool = opcao("tool");
|
|
61
|
+
const erro = await verificarNoAr({
|
|
62
|
+
url,
|
|
63
|
+
caminhoDaTrava: opcao("trava") ?? "surface.lock.json",
|
|
64
|
+
...(opcao("config") ? { config: opcao("config") } : {}),
|
|
65
|
+
...(opcao("rota") ? { rota: opcao("rota") } : {}),
|
|
66
|
+
...(tool ? { chamada: { name: tool, arguments: JSON.parse(opcao("args") ?? "{}") } } : {}),
|
|
67
|
+
log: linha => console.log(linha),
|
|
68
|
+
});
|
|
69
|
+
if (erro) {
|
|
70
|
+
console.error(`O que está no ar NÃO é o que foi travado: ${erro}`);
|
|
71
|
+
return 1;
|
|
72
|
+
}
|
|
73
|
+
return 0;
|
|
74
|
+
}
|
|
75
|
+
if (comando === "replay") {
|
|
76
|
+
const pkg = lerJson("package.json");
|
|
77
|
+
const server = lerJson("server.json");
|
|
78
|
+
const pacote = opcao("pacote") ?? pkg?.["name"];
|
|
79
|
+
if (!pacote) {
|
|
80
|
+
console.error("uso: mcp-surface replay --pacote <nome npm> (ou rode na raiz do pacote)");
|
|
81
|
+
return 2;
|
|
82
|
+
}
|
|
83
|
+
const registro = opcao("registro") ?? server?.["name"];
|
|
84
|
+
const url = opcao("url");
|
|
85
|
+
const { markdown, json } = await replay({
|
|
86
|
+
pacote,
|
|
87
|
+
...(registro ? { nomeNoRegistro: registro } : {}),
|
|
88
|
+
...(url ? { url } : {}),
|
|
89
|
+
log: linha => console.log(linha),
|
|
90
|
+
});
|
|
91
|
+
const base = join(opcao("saida") ?? "baselines", `replay-${new Date().toISOString().slice(0, 10)}`);
|
|
92
|
+
writeFileSync(`${base}.md`, markdown);
|
|
93
|
+
writeFileSync(`${base}.json`, `${JSON.stringify(json, null, 2)}\n`);
|
|
94
|
+
console.log(`\n${base}.md\n${base}.json`);
|
|
95
|
+
return 0;
|
|
96
|
+
}
|
|
97
|
+
console.error("uso: mcp-surface <travar|verificar|replay> … (ver o cabeçalho de src/cli.ts ou o README)");
|
|
98
|
+
return 2;
|
|
99
|
+
}
|
|
100
|
+
process.exit(await main());
|
|
101
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { PROTOCOLO_DA_CAPTURA, capturarPor, impressaoDigital, normalizarSuperficie, paramsDoInitialize, type SuperficieBruta, } from "./superficie.js";
|
|
2
|
+
export { capturarSuperficie, type ServidorConectavel } from "./memoria.js";
|
|
3
|
+
export { CABECALHOS_MCP, comHost, corpoDoPedido, ipDaSonda, lerCorpoJsonRpc, medirSemToken, respondeu, sondaSemToken, type ChamadaLocal, type Pedido, } from "./sonda.js";
|
|
4
|
+
export { VAR_ESCRITA, conferirSecao, lerTrava, modoEscrita, type NomeDaSecao, type Trava, type Veredito } from "./trava.js";
|
|
5
|
+
export { capturarHttp, capturarStdio, pedirHttp } from "./remoto.js";
|
|
6
|
+
export { verificarNoAr, type OpcoesVerificar } from "./verificar.js";
|
|
7
|
+
export { diferenca, replay, type OpcoesReplay } from "./replay.js";
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,WAAW,EACX,gBAAgB,EAChB,oBAAoB,EACpB,kBAAkB,EAClB,KAAK,eAAe,GACrB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,kBAAkB,EAAE,KAAK,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAC3E,OAAO,EACL,cAAc,EACd,OAAO,EACP,aAAa,EACb,SAAS,EACT,eAAe,EACf,aAAa,EACb,SAAS,EACT,aAAa,EACb,KAAK,YAAY,EACjB,KAAK,MAAM,GACZ,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,KAAK,KAAK,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC5H,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { PROTOCOLO_DA_CAPTURA, capturarPor, impressaoDigital, normalizarSuperficie, paramsDoInitialize, } from "./superficie.js";
|
|
2
|
+
export { capturarSuperficie } from "./memoria.js";
|
|
3
|
+
export { CABECALHOS_MCP, comHost, corpoDoPedido, ipDaSonda, lerCorpoJsonRpc, medirSemToken, respondeu, sondaSemToken, } from "./sonda.js";
|
|
4
|
+
export { VAR_ESCRITA, conferirSecao, lerTrava, modoEscrita } from "./trava.js";
|
|
5
|
+
export { capturarHttp, capturarStdio, pedirHttp } from "./remoto.js";
|
|
6
|
+
export { verificarNoAr } from "./verificar.js";
|
|
7
|
+
export { diferenca, replay } from "./replay.js";
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,WAAW,EACX,gBAAgB,EAChB,oBAAoB,EACpB,kBAAkB,GAEnB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,kBAAkB,EAA2B,MAAM,cAAc,CAAC;AAC3E,OAAO,EACL,cAAc,EACd,OAAO,EACP,aAAa,EACb,SAAS,EACT,eAAe,EACf,aAAa,EACb,SAAS,EACT,aAAa,GAGd,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,QAAQ,EAAE,WAAW,EAA+C,MAAM,YAAY,CAAC;AAC5H,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EAAE,aAAa,EAAwB,MAAM,gBAAgB,CAAC;AACrE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAqB,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Captura em memória: o servidor montado pela mesma fábrica que os transportes
|
|
3
|
+
* usam, interrogado por JSON-RPC cru sobre o `InMemoryTransport` do SDK v2.
|
|
4
|
+
*
|
|
5
|
+
* JSON-RPC cru, e não o `Client` do SDK: o `Client` compila os `outputSchema`
|
|
6
|
+
* com Ajv (`new Function`), que o runtime da Cloudflare proíbe — o mesmo
|
|
7
|
+
* caminho serve teste em Node e código de Worker.
|
|
8
|
+
*/
|
|
9
|
+
import { InMemoryTransport } from "@modelcontextprotocol/server";
|
|
10
|
+
/** O que a captura precisa de um `McpServer`: só conectar a um transporte. */
|
|
11
|
+
export interface ServidorConectavel {
|
|
12
|
+
connect(transport: InMemoryTransport): Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
export declare function capturarSuperficie(server: ServidorConectavel): Promise<Record<string, unknown>>;
|
|
15
|
+
//# sourceMappingURL=memoria.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memoria.d.ts","sourceRoot":"","sources":["../src/memoria.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAIjE,8EAA8E;AAC9E,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,SAAS,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACtD;AAED,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CA+BrG"}
|
package/dist/memoria.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Captura em memória: o servidor montado pela mesma fábrica que os transportes
|
|
3
|
+
* usam, interrogado por JSON-RPC cru sobre o `InMemoryTransport` do SDK v2.
|
|
4
|
+
*
|
|
5
|
+
* JSON-RPC cru, e não o `Client` do SDK: o `Client` compila os `outputSchema`
|
|
6
|
+
* com Ajv (`new Function`), que o runtime da Cloudflare proíbe — o mesmo
|
|
7
|
+
* caminho serve teste em Node e código de Worker.
|
|
8
|
+
*/
|
|
9
|
+
import { InMemoryTransport } from "@modelcontextprotocol/server";
|
|
10
|
+
import { capturarPor } from "./superficie.js";
|
|
11
|
+
export async function capturarSuperficie(server) {
|
|
12
|
+
const [cliente, lado] = InMemoryTransport.createLinkedPair();
|
|
13
|
+
await server.connect(lado);
|
|
14
|
+
const pendentes = new Map();
|
|
15
|
+
cliente.onmessage = (msg) => {
|
|
16
|
+
const m = msg;
|
|
17
|
+
if (typeof m.id === "number") {
|
|
18
|
+
pendentes.get(m.id)?.(m);
|
|
19
|
+
pendentes.delete(m.id);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
await cliente.start();
|
|
23
|
+
let proximo = 1;
|
|
24
|
+
const pedir = (method, params) => new Promise(resolve => {
|
|
25
|
+
const id = proximo++;
|
|
26
|
+
pendentes.set(id, msg => resolve(msg.error ? undefined : msg.result));
|
|
27
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
28
|
+
void cliente.send({ jsonrpc: "2.0", id, method, params });
|
|
29
|
+
});
|
|
30
|
+
try {
|
|
31
|
+
return await capturarPor(pedir, "surface-lock", () => {
|
|
32
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
33
|
+
void cliente.send({ jsonrpc: "2.0", method: "notifications/initialized" });
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
finally {
|
|
37
|
+
await cliente.close();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=memoria.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memoria.js","sourceRoot":"","sources":["../src/memoria.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAEjE,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAO9C,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,MAA0B;IACjE,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,iBAAiB,CAAC,gBAAgB,EAAE,CAAC;IAC7D,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAE3B,MAAM,SAAS,GAAG,IAAI,GAAG,EAAgF,CAAC;IAC1G,OAAO,CAAC,SAAS,GAAG,CAAC,GAAY,EAAE,EAAE;QACnC,MAAM,CAAC,GAAG,GAA0E,CAAC;QACrF,IAAI,OAAO,CAAC,CAAC,EAAE,KAAK,QAAQ,EAAE,CAAC;YAC7B,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACzB,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACzB,CAAC;IACH,CAAC,CAAC;IACF,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IAEtB,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,MAAM,KAAK,GAAG,CAAC,MAAc,EAAE,MAAgC,EAAE,EAAE,CACjE,IAAI,OAAO,CAAsC,OAAO,CAAC,EAAE;QACzD,MAAM,EAAE,GAAG,OAAO,EAAE,CAAC;QACrB,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;QACtE,8DAA8D;QAC9D,KAAK,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAS,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;IAEL,IAAI,CAAC;QACH,OAAO,MAAM,WAAW,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE;YACnD,8DAA8D;YAC9D,KAAK,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,2BAA2B,EAAS,CAAC,CAAC;QACpF,CAAC,CAAC,CAAC;IACL,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;AACH,CAAC"}
|
package/dist/remoto.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Captura por fora: um endpoint HTTP no ar, ou o pacote de uma versão
|
|
3
|
+
* publicada rodando em stdio. Os dois passam pela mesma normalização da
|
|
4
|
+
* captura em memória — é o que permite comparar o ar com a trava e uma versão
|
|
5
|
+
* antiga com a de hoje.
|
|
6
|
+
*/
|
|
7
|
+
import { type Pedido } from "./sonda.js";
|
|
8
|
+
/** Um pedido JSON-RPC a um endpoint MCP, sem credencial. */
|
|
9
|
+
export declare function pedirHttp(url: string, pedido: Pedido): Promise<{
|
|
10
|
+
status: number;
|
|
11
|
+
result?: Record<string, unknown>;
|
|
12
|
+
}>;
|
|
13
|
+
/** A superfície declarada servida por um endpoint HTTP (stateless, sem credencial). */
|
|
14
|
+
export declare function capturarHttp(url: string): Promise<Record<string, unknown>>;
|
|
15
|
+
/** A superfície de um servidor stdio (`node <entrada>`), como um cliente local a veria. */
|
|
16
|
+
export declare function capturarStdio(entrada: string, env?: NodeJS.ProcessEnv): Promise<Record<string, unknown>>;
|
|
17
|
+
//# sourceMappingURL=remoto.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remoto.d.ts","sourceRoot":"","sources":["../src/remoto.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAkD,KAAK,MAAM,EAAE,MAAM,YAAY,CAAC;AAGzF,4DAA4D;AAC5D,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC,CAI1H;AAED,uFAAuF;AACvF,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAK1E;AAED,2FAA2F;AAC3F,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAwC3H"}
|
package/dist/remoto.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Captura por fora: um endpoint HTTP no ar, ou o pacote de uma versão
|
|
3
|
+
* publicada rodando em stdio. Os dois passam pela mesma normalização da
|
|
4
|
+
* captura em memória — é o que permite comparar o ar com a trava e uma versão
|
|
5
|
+
* antiga com a de hoje.
|
|
6
|
+
*/
|
|
7
|
+
import { spawn } from "node:child_process";
|
|
8
|
+
import { CABECALHOS_MCP, corpoDoPedido, lerCorpoJsonRpc } from "./sonda.js";
|
|
9
|
+
import { capturarPor } from "./superficie.js";
|
|
10
|
+
/** Um pedido JSON-RPC a um endpoint MCP, sem credencial. */
|
|
11
|
+
export async function pedirHttp(url, pedido) {
|
|
12
|
+
const res = await fetch(url, { method: "POST", headers: { ...CABECALHOS_MCP }, body: corpoDoPedido(pedido) });
|
|
13
|
+
const corpo = lerCorpoJsonRpc(await res.text());
|
|
14
|
+
return corpo?.result ? { status: res.status, result: corpo.result } : { status: res.status };
|
|
15
|
+
}
|
|
16
|
+
/** A superfície declarada servida por um endpoint HTTP (stateless, sem credencial). */
|
|
17
|
+
export function capturarHttp(url) {
|
|
18
|
+
return capturarPor(async (method, params) => {
|
|
19
|
+
const pedido = params ? { method, params } : { method };
|
|
20
|
+
return (await pedirHttp(url, pedido)).result;
|
|
21
|
+
}, "mcp-surface");
|
|
22
|
+
}
|
|
23
|
+
/** A superfície de um servidor stdio (`node <entrada>`), como um cliente local a veria. */
|
|
24
|
+
export async function capturarStdio(entrada, env = process.env) {
|
|
25
|
+
const filho = spawn(process.execPath, [entrada], { stdio: ["pipe", "pipe", "ignore"], env });
|
|
26
|
+
let buffer = "";
|
|
27
|
+
const pendentes = new Map();
|
|
28
|
+
filho.stdout.on("data", (pedaco) => {
|
|
29
|
+
buffer += pedaco.toString();
|
|
30
|
+
let nl;
|
|
31
|
+
while ((nl = buffer.indexOf("\n")) >= 0) {
|
|
32
|
+
const linha = buffer.slice(0, nl).trim();
|
|
33
|
+
buffer = buffer.slice(nl + 1);
|
|
34
|
+
let msg;
|
|
35
|
+
try {
|
|
36
|
+
msg = JSON.parse(linha);
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
continue; // log solto no stdout
|
|
40
|
+
}
|
|
41
|
+
if (typeof msg.id === "number") {
|
|
42
|
+
pendentes.get(msg.id)?.(msg);
|
|
43
|
+
pendentes.delete(msg.id);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
let id = 1;
|
|
48
|
+
const escrever = (msg) => filho.stdin.write(`${JSON.stringify(msg)}\n`);
|
|
49
|
+
const pedir = (method, params) => new Promise(resolve => {
|
|
50
|
+
const meu = id++;
|
|
51
|
+
pendentes.set(meu, msg => resolve(msg.error ? undefined : msg.result));
|
|
52
|
+
escrever({ jsonrpc: "2.0", id: meu, method, params });
|
|
53
|
+
setTimeout(() => {
|
|
54
|
+
if (pendentes.delete(meu))
|
|
55
|
+
resolve(undefined);
|
|
56
|
+
}, 20_000);
|
|
57
|
+
});
|
|
58
|
+
try {
|
|
59
|
+
return await capturarPor(pedir, "mcp-surface-replay", () => escrever({ jsonrpc: "2.0", method: "notifications/initialized" }));
|
|
60
|
+
}
|
|
61
|
+
finally {
|
|
62
|
+
filho.kill();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=remoto.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remoto.js","sourceRoot":"","sources":["../src/remoto.ts"],"names":[],"mappings":"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"}
|
package/dist/replay.d.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* REPLAY RETROATIVO: cada versão publicada no npm, instalada num diretório
|
|
3
|
+
* temporário e interrogada por stdio, normalizada com a mesma função da trava;
|
|
4
|
+
* e o endpoint no ar comparado com a versão que o `/status` dele declara.
|
|
5
|
+
*
|
|
6
|
+
* A trava só protege daqui para a frente. A prova que achou o caso grave do
|
|
7
|
+
* leitor do dev.to (3g607) foi um replay — a superfície do dia da listagem
|
|
8
|
+
* contra a de hoje. Aqui o equivalente é rodar o histórico inteiro uma vez: o
|
|
9
|
+
* que mudou entre versões vizinhas, se alguma remoção saiu fora de major, e se
|
|
10
|
+
* o ar serve a superfície da versão que anuncia.
|
|
11
|
+
*/
|
|
12
|
+
export interface OpcoesReplay {
|
|
13
|
+
pacote: string;
|
|
14
|
+
/** Nome no MCP Registry (o `name` do server.json), para a coluna "registrada". */
|
|
15
|
+
nomeNoRegistro?: string;
|
|
16
|
+
/** Endpoint MCP no ar; o `/status` é lido no mesmo host. */
|
|
17
|
+
url?: string;
|
|
18
|
+
/** Ambiente do servidor stdio (ex.: fixar uma flag que muda a superfície). */
|
|
19
|
+
env?: NodeJS.ProcessEnv;
|
|
20
|
+
log?: (linha: string) => void;
|
|
21
|
+
}
|
|
22
|
+
type Item = Record<string, unknown>;
|
|
23
|
+
/** O que mudou de uma versão para a seguinte, e o que disso quebra cliente. */
|
|
24
|
+
export declare function diferenca(antes: Item, depois: Item): {
|
|
25
|
+
tools: {
|
|
26
|
+
mais: string[];
|
|
27
|
+
menos: string[];
|
|
28
|
+
mudou: string[];
|
|
29
|
+
};
|
|
30
|
+
resources: {
|
|
31
|
+
mais: string[];
|
|
32
|
+
menos: string[];
|
|
33
|
+
};
|
|
34
|
+
prompts: {
|
|
35
|
+
mais: string[];
|
|
36
|
+
menos: string[];
|
|
37
|
+
};
|
|
38
|
+
quebras: string[];
|
|
39
|
+
instructions: boolean;
|
|
40
|
+
capabilities: boolean;
|
|
41
|
+
identidade: boolean;
|
|
42
|
+
};
|
|
43
|
+
export declare function replay(o: OpcoesReplay): Promise<{
|
|
44
|
+
markdown: string;
|
|
45
|
+
json: unknown;
|
|
46
|
+
}>;
|
|
47
|
+
export {};
|
|
48
|
+
//# sourceMappingURL=replay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"replay.d.ts","sourceRoot":"","sources":["../src/replay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAYH,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,kFAAkF;IAClF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,4DAA4D;IAC5D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/B;AAWD,KAAK,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAYpC,+EAA+E;AAC/E,wBAAgB,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI;;QAEtC,IAAI,EAAQ,MAAM,EAAE;QAAE,KAAK,EAAQ,MAAM,EAAE;QAAE,KAAK,EAAQ,MAAM,EAAE;;;QAC9D,IAAI,EAAQ,MAAM,EAAE;QAAE,KAAK,EAAQ,MAAM,EAAE;;;QAC7C,IAAI,EAAQ,MAAM,EAAE;QAAE,KAAK,EAAQ,MAAM,EAAE;;aACvC,MAAM,EAAE;;;;EA2C1B;AAID,wBAAsB,MAAM,CAAC,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC,CA8I1F"}
|