@brazil-mcp/cnpj 1.0.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 ADDED
@@ -0,0 +1,75 @@
1
+ # 🇧🇷 CNPJ MCP Server
2
+
3
+ MCP server para consulta de CNPJ, sĂłcios e atividades de empresas brasileiras.
4
+
5
+ Parte do [Brazil MCP Bundle](https://github.com/acaua/brazil-mcp) — ferramentas brasileiras para Claude Code, Cursor e qualquer cliente MCP.
6
+
7
+ ---
8
+
9
+ ## Instalação
10
+
11
+ ```bash
12
+ # Claude Code
13
+ claude mcp add cnpj -- npx @brazil-mcp/cnpj
14
+
15
+ # claude_desktop_config.json / Cursor / VS Code
16
+ {
17
+ "mcpServers": {
18
+ "cnpj": {
19
+ "command": "npx",
20
+ "args": ["@brazil-mcp/cnpj"]
21
+ }
22
+ }
23
+ }
24
+ ```
25
+
26
+ ## Tools DisponĂ­veis
27
+
28
+ | Tool | Descrição |
29
+ |------|-----------|
30
+ | `cnpj_lookup` | Dados completos da empresa (razão social, endereço, capital social, sócios, CNAEs) |
31
+ | `cnpj_validate` | Valida dĂ­gitos verificadores (local, sem API) |
32
+ | `cnpj_partners` | Lista de sócios (QSA) com qualificação |
33
+ | `cnpj_activities` | Atividades econômicas (CNAE principal e secundárias) |
34
+ | `cnpj_address` | Endereço completo registrado na Receita Federal |
35
+
36
+ ## Exemplos de Uso
37
+
38
+ No Claude Code ou Cursor, simplesmente peça:
39
+
40
+ - *"Quem sĂŁo os sĂłcios do CNPJ 33.000.167/0001-01?"*
41
+ - *"Valide o CNPJ 12345678000195"*
42
+ - *"Qual o endereço da empresa com CNPJ 33000167000101?"*
43
+ - *"Liste as atividades econĂ´micas do CNPJ 33.000.167/0001-01"*
44
+
45
+ ## APIs Utilizadas
46
+
47
+ - [BrasilAPI](https://brasilapi.com.br/) (principal — gratuita, sem auth)
48
+ - [ReceitaWS](https://receitaws.com.br/) (fallback — gratuita, 3 req/min)
49
+
50
+ Cache em memĂłria com TTL de 24h para reduzir chamadas.
51
+
52
+ ## Desenvolvimento
53
+
54
+ ```bash
55
+ npm install
56
+ npm run dev # Roda em modo dev
57
+ npm test # Testes unitários
58
+ npm run test:integration # Testes com APIs reais
59
+ npm run build # Compila TypeScript
60
+ npm run inspect # Abre MCP Inspector
61
+ ```
62
+
63
+ ## Licença
64
+
65
+ MIT
66
+
67
+ ---
68
+
69
+ # 🇧🇷 CNPJ MCP Server (English)
70
+
71
+ MCP server for querying Brazilian company data (CNPJ), partners, and economic activities.
72
+
73
+ Part of the [Brazil MCP Bundle](https://github.com/acaua/brazil-mcp) — Brazilian business tools for Claude Code, Cursor, and any MCP client.
74
+
75
+ All tool responses are in Portuguese (Brazilian data from Receita Federal).
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { createServer } from "./server.js";
4
+ async function main() {
5
+ const { server } = createServer();
6
+ const transport = new StdioServerTransport();
7
+ await server.connect(transport);
8
+ console.error("[cnpj-mcp] Server iniciado via stdio");
9
+ }
10
+ main().catch((err) => {
11
+ console.error("[cnpj-mcp] Erro fatal:", err);
12
+ process.exit(1);
13
+ });
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,KAAK,UAAU,IAAI;IACjB,MAAM,EAAE,MAAM,EAAE,GAAG,YAAY,EAAE,CAAC;IAClC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;AACxD,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,wBAAwB,EAAE,GAAG,CAAC,CAAC;IAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { CnpjData, CnpjProvider } from "../types.js";
2
+ /**
3
+ * Provider que consulta a BrasilAPI (gratuita, sem autenticação).
4
+ * Docs: https://brasilapi.com.br/docs#tag/CNPJ
5
+ */
6
+ export declare class BrasilApiProvider implements CnpjProvider {
7
+ name: string;
8
+ private baseUrl;
9
+ fetchCnpj(cnpj: string): Promise<CnpjData>;
10
+ private normalize;
11
+ }
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Provider que consulta a BrasilAPI (gratuita, sem autenticação).
3
+ * Docs: https://brasilapi.com.br/docs#tag/CNPJ
4
+ */
5
+ export class BrasilApiProvider {
6
+ name = "BrasilAPI";
7
+ baseUrl = "https://brasilapi.com.br/api/cnpj/v1";
8
+ async fetchCnpj(cnpj) {
9
+ const url = `${this.baseUrl}/${cnpj}`;
10
+ const response = await fetch(url, {
11
+ headers: { Accept: "application/json" },
12
+ signal: AbortSignal.timeout(10_000),
13
+ });
14
+ if (!response.ok) {
15
+ const status = response.status;
16
+ if (status === 404) {
17
+ throw new Error(`CNPJ ${cnpj} nĂŁo encontrado na base da Receita Federal.`);
18
+ }
19
+ if (status === 429) {
20
+ throw new Error("Rate limit atingido na BrasilAPI. Tente novamente em alguns segundos.");
21
+ }
22
+ throw new Error(`BrasilAPI retornou status ${status}`);
23
+ }
24
+ const raw = await response.json();
25
+ return this.normalize(raw);
26
+ }
27
+ normalize(raw) {
28
+ const socios = (raw.qsa || []).map((s) => ({
29
+ nome: s.nome_socio || s.nome || "",
30
+ qualificacao: s.qualificacao_socio || s.qual || "",
31
+ data_entrada: s.data_entrada_sociedade || "",
32
+ cpf_cnpj: s.cnpj_cpf_do_socio || "",
33
+ faixa_etaria: s.faixa_etaria || "",
34
+ }));
35
+ const atividadePrincipal = {
36
+ codigo: String(raw.cnae_fiscal || ""),
37
+ descricao: raw.cnae_fiscal_descricao || "",
38
+ };
39
+ const atividadesSecundarias = (raw.cnaes_secundarios || []).map((a) => ({
40
+ codigo: String(a.codigo || ""),
41
+ descricao: a.descricao || "",
42
+ }));
43
+ return {
44
+ cnpj: raw.cnpj || "",
45
+ razao_social: raw.razao_social || "",
46
+ nome_fantasia: raw.nome_fantasia || "",
47
+ situacao_cadastral: raw.descricao_situacao_cadastral || "",
48
+ data_situacao_cadastral: raw.data_situacao_cadastral || "",
49
+ data_abertura: raw.data_inicio_atividade || "",
50
+ natureza_juridica: raw.natureza_juridica || "",
51
+ capital_social: raw.capital_social || 0,
52
+ porte: raw.porte || raw.descricao_porte || "",
53
+ tipo: raw.descricao_tipo_de_logradouro || "",
54
+ logradouro: raw.logradouro || "",
55
+ numero: raw.numero || "",
56
+ complemento: raw.complemento || "",
57
+ bairro: raw.bairro || "",
58
+ municipio: raw.municipio || "",
59
+ uf: raw.uf || "",
60
+ cep: raw.cep || "",
61
+ telefone: raw.ddd_telefone_1 || "",
62
+ email: raw.email || "",
63
+ atividade_principal: atividadePrincipal,
64
+ atividades_secundarias: atividadesSecundarias,
65
+ socios,
66
+ };
67
+ }
68
+ }
69
+ //# sourceMappingURL=brasil-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"brasil-api.js","sourceRoot":"","sources":["../../src/providers/brasil-api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { CnpjData, CnpjProvider } from "../types.js";
2
+ import { MemoryCache } from "../utils/cache.js";
3
+ /**
4
+ * Orquestrador de providers CNPJ com fallback automático e cache.
5
+ *
6
+ * Fluxo:
7
+ * 1. Verifica cache (TTL 24h)
8
+ * 2. Tenta BrasilAPI (principal)
9
+ * 3. Se falhar, tenta ReceitaWS (fallback)
10
+ * 4. Se ambos falharem, retorna erro descritivo
11
+ */
12
+ export declare class CnpjService {
13
+ private providers;
14
+ private cache;
15
+ constructor(providers?: CnpjProvider[], cache?: MemoryCache<CnpjData>);
16
+ lookup(cnpj: string): Promise<CnpjData>;
17
+ clearCache(): void;
18
+ get cacheSize(): number;
19
+ }
@@ -0,0 +1,56 @@
1
+ import { MemoryCache } from "../utils/cache.js";
2
+ import { BrasilApiProvider } from "./brasil-api.js";
3
+ import { ReceitaWsProvider } from "./receita-ws.js";
4
+ /**
5
+ * Orquestrador de providers CNPJ com fallback automático e cache.
6
+ *
7
+ * Fluxo:
8
+ * 1. Verifica cache (TTL 24h)
9
+ * 2. Tenta BrasilAPI (principal)
10
+ * 3. Se falhar, tenta ReceitaWS (fallback)
11
+ * 4. Se ambos falharem, retorna erro descritivo
12
+ */
13
+ export class CnpjService {
14
+ providers;
15
+ cache;
16
+ constructor(providers, cache) {
17
+ this.providers = providers ?? [
18
+ new BrasilApiProvider(),
19
+ new ReceitaWsProvider(),
20
+ ];
21
+ this.cache = cache ?? new MemoryCache(86_400_000); // 24h
22
+ }
23
+ async lookup(cnpj) {
24
+ // 1. Verifica cache
25
+ const cached = this.cache.get(cnpj);
26
+ if (cached) {
27
+ console.error(`[cnpj-mcp] Cache hit para ${cnpj}`);
28
+ return cached;
29
+ }
30
+ // 2. Tenta cada provider em ordem
31
+ const errors = [];
32
+ for (const provider of this.providers) {
33
+ try {
34
+ console.error(`[cnpj-mcp] Consultando ${provider.name} para ${cnpj}`);
35
+ const data = await provider.fetchCnpj(cnpj);
36
+ this.cache.set(cnpj, data);
37
+ return data;
38
+ }
39
+ catch (err) {
40
+ const message = err instanceof Error ? err.message : String(err);
41
+ console.error(`[cnpj-mcp] ${provider.name} falhou: ${message}`);
42
+ errors.push(`${provider.name}: ${message}`);
43
+ }
44
+ }
45
+ // 3. Todos falharam
46
+ throw new Error(`NĂŁo foi possĂ­vel consultar o CNPJ ${cnpj}. ` +
47
+ `Erros: ${errors.join(" | ")}`);
48
+ }
49
+ clearCache() {
50
+ this.cache.clear();
51
+ }
52
+ get cacheSize() {
53
+ return this.cache.size;
54
+ }
55
+ }
56
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEpD;;;;;;;;GAQG;AACH,MAAM,OAAO,WAAW;IACd,SAAS,CAAiB;IAC1B,KAAK,CAAwB;IAErC,YACE,SAA0B,EAC1B,KAA6B;QAE7B,IAAI,CAAC,SAAS,GAAG,SAAS,IAAI;YAC5B,IAAI,iBAAiB,EAAE;YACvB,IAAI,iBAAiB,EAAE;SACxB,CAAC;QACF,IAAI,CAAC,KAAK,GAAG,KAAK,IAAI,IAAI,WAAW,CAAW,UAAU,CAAC,CAAC,CAAC,MAAM;IACrE,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,oBAAoB;QACpB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,6BAA6B,IAAI,EAAE,CAAC,CAAC;YACnD,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,kCAAkC;QAClC,MAAM,MAAM,GAAa,EAAE,CAAC;QAE5B,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACtC,IAAI,CAAC;gBACH,OAAO,CAAC,KAAK,CAAC,0BAA0B,QAAQ,CAAC,IAAI,SAAS,IAAI,EAAE,CAAC,CAAC;gBACtE,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;gBAC5C,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;gBAC3B,OAAO,IAAI,CAAC;YACd,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBACjE,OAAO,CAAC,KAAK,CAAC,cAAc,QAAQ,CAAC,IAAI,YAAY,OAAO,EAAE,CAAC,CAAC;gBAChE,MAAM,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC,CAAC;YAC9C,CAAC;QACH,CAAC;QAED,oBAAoB;QACpB,MAAM,IAAI,KAAK,CACb,qCAAqC,IAAI,IAAI;YAC3C,UAAU,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CACjC,CAAC;IACJ,CAAC;IAED,UAAU;QACR,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;IAED,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;IACzB,CAAC;CACF"}
@@ -0,0 +1,12 @@
1
+ import type { CnpjData, CnpjProvider } from "../types.js";
2
+ /**
3
+ * Provider que consulta a ReceitaWS (gratuita, limite 3 req/min).
4
+ * Usado como fallback quando BrasilAPI está indisponível.
5
+ * Docs: https://receitaws.com.br/api
6
+ */
7
+ export declare class ReceitaWsProvider implements CnpjProvider {
8
+ name: string;
9
+ private baseUrl;
10
+ fetchCnpj(cnpj: string): Promise<CnpjData>;
11
+ private normalize;
12
+ }
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Provider que consulta a ReceitaWS (gratuita, limite 3 req/min).
3
+ * Usado como fallback quando BrasilAPI está indisponível.
4
+ * Docs: https://receitaws.com.br/api
5
+ */
6
+ export class ReceitaWsProvider {
7
+ name = "ReceitaWS";
8
+ baseUrl = "https://receitaws.com.br/v1/cnpj";
9
+ async fetchCnpj(cnpj) {
10
+ const url = `${this.baseUrl}/${cnpj}`;
11
+ const response = await fetch(url, {
12
+ headers: { Accept: "application/json" },
13
+ signal: AbortSignal.timeout(15_000), // ReceitaWS Ă© mais lenta
14
+ });
15
+ if (!response.ok) {
16
+ throw new Error(`ReceitaWS retornou status ${response.status}`);
17
+ }
18
+ const raw = await response.json();
19
+ if (raw.status === "ERROR") {
20
+ throw new Error(raw.message || "Erro ao consultar ReceitaWS");
21
+ }
22
+ return this.normalize(raw);
23
+ }
24
+ normalize(raw) {
25
+ const socios = (raw.qsa || []).map((s) => ({
26
+ nome: s.nome || "",
27
+ qualificacao: s.qual || "",
28
+ data_entrada: "",
29
+ cpf_cnpj: "",
30
+ faixa_etaria: "",
31
+ }));
32
+ const parseActivity = (a) => ({
33
+ codigo: a.code || "",
34
+ descricao: a.text || "",
35
+ });
36
+ const atividadePrincipal = raw.atividade_principal?.length > 0
37
+ ? parseActivity(raw.atividade_principal[0])
38
+ : { codigo: "", descricao: "" };
39
+ const atividadesSecundarias = (raw.atividades_secundarias || []).map(parseActivity);
40
+ return {
41
+ cnpj: (raw.cnpj || "").replace(/[^\d]/g, ""),
42
+ razao_social: raw.nome || "",
43
+ nome_fantasia: raw.fantasia || "",
44
+ situacao_cadastral: raw.situacao || "",
45
+ data_situacao_cadastral: raw.data_situacao || "",
46
+ data_abertura: raw.abertura || "",
47
+ natureza_juridica: raw.natureza_juridica || "",
48
+ capital_social: parseFloat(raw.capital_social || "0"),
49
+ porte: raw.porte || "",
50
+ tipo: raw.tipo || "",
51
+ logradouro: raw.logradouro || "",
52
+ numero: raw.numero || "",
53
+ complemento: raw.complemento || "",
54
+ bairro: raw.bairro || "",
55
+ municipio: raw.municipio || "",
56
+ uf: raw.uf || "",
57
+ cep: (raw.cep || "").replace(/[^\d]/g, ""),
58
+ telefone: raw.telefone || "",
59
+ email: raw.email || "",
60
+ atividade_principal: atividadePrincipal,
61
+ atividades_secundarias: atividadesSecundarias,
62
+ socios,
63
+ };
64
+ }
65
+ }
66
+ //# sourceMappingURL=receita-ws.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"receita-ws.js","sourceRoot":"","sources":["../../src/providers/receita-ws.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,OAAO,iBAAiB;IAC5B,IAAI,GAAG,WAAW,CAAC;IACX,OAAO,GAAG,kCAAkC,CAAC;IAErD,KAAK,CAAC,SAAS,CAAC,IAAY;QAC1B,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,IAAI,IAAI,EAAE,CAAC;QAEtC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,OAAO,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE;YACvC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,yBAAyB;SAC/D,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,6BAA6B,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QAClE,CAAC;QAED,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QAElC,IAAI,GAAG,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,OAAO,IAAI,6BAA6B,CAAC,CAAC;QAChE,CAAC;QAED,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAEO,SAAS,CAAC,GAAwB;QACxC,MAAM,MAAM,GAAkB,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC;YAC7D,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,EAAE;YAClB,YAAY,EAAE,CAAC,CAAC,IAAI,IAAI,EAAE;YAC1B,YAAY,EAAE,EAAE;YAChB,QAAQ,EAAE,EAAE;YACZ,YAAY,EAAE,EAAE;SACjB,CAAC,CAAC,CAAC;QAEJ,MAAM,aAAa,GAAG,CAAC,CAAM,EAAgB,EAAE,CAAC,CAAC;YAC/C,MAAM,EAAE,CAAC,CAAC,IAAI,IAAI,EAAE;YACpB,SAAS,EAAE,CAAC,CAAC,IAAI,IAAI,EAAE;SACxB,CAAC,CAAC;QAEH,MAAM,kBAAkB,GACtB,GAAG,CAAC,mBAAmB,EAAE,MAAM,GAAG,CAAC;YACjC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;YAC3C,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;QAEpC,MAAM,qBAAqB,GAAmB,CAC5C,GAAG,CAAC,sBAAsB,IAAI,EAAE,CACjC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QAErB,OAAO;YACL,IAAI,EAAE,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;YAC5C,YAAY,EAAE,GAAG,CAAC,IAAI,IAAI,EAAE;YAC5B,aAAa,EAAE,GAAG,CAAC,QAAQ,IAAI,EAAE;YACjC,kBAAkB,EAAE,GAAG,CAAC,QAAQ,IAAI,EAAE;YACtC,uBAAuB,EAAE,GAAG,CAAC,aAAa,IAAI,EAAE;YAChD,aAAa,EAAE,GAAG,CAAC,QAAQ,IAAI,EAAE;YACjC,iBAAiB,EAAE,GAAG,CAAC,iBAAiB,IAAI,EAAE;YAC9C,cAAc,EAAE,UAAU,CAAC,GAAG,CAAC,cAAc,IAAI,GAAG,CAAC;YACrD,KAAK,EAAE,GAAG,CAAC,KAAK,IAAI,EAAE;YACtB,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,EAAE;YAEpB,UAAU,EAAE,GAAG,CAAC,UAAU,IAAI,EAAE;YAChC,MAAM,EAAE,GAAG,CAAC,MAAM,IAAI,EAAE;YACxB,WAAW,EAAE,GAAG,CAAC,WAAW,IAAI,EAAE;YAClC,MAAM,EAAE,GAAG,CAAC,MAAM,IAAI,EAAE;YACxB,SAAS,EAAE,GAAG,CAAC,SAAS,IAAI,EAAE;YAC9B,EAAE,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE;YAChB,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;YAE1C,QAAQ,EAAE,GAAG,CAAC,QAAQ,IAAI,EAAE;YAC5B,KAAK,EAAE,GAAG,CAAC,KAAK,IAAI,EAAE;YAEtB,mBAAmB,EAAE,kBAAkB;YACvC,sBAAsB,EAAE,qBAAqB;YAC7C,MAAM;SACP,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,16 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { CnpjService } from "./providers/index.js";
3
+ import { DailyRateLimiter } from "./utils/rate-limiter.js";
4
+ /**
5
+ * Cria e configura o MCP Server com todas as tools.
6
+ * No tier free, aplica rate limit de 50 calls/dia nas tools que consultam API.
7
+ * cnpj_validate nĂŁo consome quota (Ă© local).
8
+ */
9
+ export declare function createServer(opts?: {
10
+ service?: CnpjService;
11
+ rateLimiter?: DailyRateLimiter | null;
12
+ }): {
13
+ server: McpServer;
14
+ cnpjService: CnpjService;
15
+ rateLimiter: DailyRateLimiter | null;
16
+ };
package/dist/server.js ADDED
@@ -0,0 +1,57 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { z } from "zod";
3
+ import { CnpjService } from "./providers/index.js";
4
+ import { handleCnpjLookup, handleCnpjValidate, handleCnpjPartners, handleCnpjActivities, handleCnpjAddress, } from "./tools/handlers.js";
5
+ import { DailyRateLimiter, rateLimitMessage } from "./utils/rate-limiter.js";
6
+ /**
7
+ * Cria e configura o MCP Server com todas as tools.
8
+ * No tier free, aplica rate limit de 50 calls/dia nas tools que consultam API.
9
+ * cnpj_validate nĂŁo consome quota (Ă© local).
10
+ */
11
+ export function createServer(opts) {
12
+ const cnpjService = opts?.service ?? new CnpjService();
13
+ // null = sem rate limit (modo pro). undefined = cria default (modo free).
14
+ const limiter = opts?.rateLimiter === null
15
+ ? null
16
+ : opts?.rateLimiter ?? new DailyRateLimiter(50);
17
+ const server = new McpServer({
18
+ name: "cnpj-mcp",
19
+ version: "1.0.0",
20
+ description: "Consulta CNPJ, sĂłcios e atividades de empresas brasileiras via Receita Federal. " +
21
+ "Plano gratuito: 50 consultas/dia. Ilimitado com @brazil-mcp/bundle-pro.",
22
+ });
23
+ function withLimit(fn, toolLabel) {
24
+ if (limiter && !limiter.tryConsume()) {
25
+ return Promise.resolve({
26
+ content: [{ type: "text", text: rateLimitMessage(toolLabel, limiter.limit) }],
27
+ });
28
+ }
29
+ return fn();
30
+ }
31
+ // ─── Tools ────────────────────────────────────────────
32
+ server.registerTool("cnpj_lookup", {
33
+ description: "Consulta dados completos de uma empresa brasileira pelo CNPJ. " +
34
+ "Retorna razão social, nome fantasia, endereço, capital social, sócios e CNAEs.",
35
+ inputSchema: {
36
+ cnpj: z.string().describe("CNPJ da empresa (com ou sem formatação)"),
37
+ },
38
+ }, async ({ cnpj }) => withLimit(() => handleCnpjLookup(cnpj, cnpjService), "CNPJ"));
39
+ server.registerTool("cnpj_validate", {
40
+ description: "Valida dĂ­gitos verificadores de um CNPJ (local, sem API, sem consumir quota).",
41
+ inputSchema: { cnpj: z.string().describe("CNPJ para validar") },
42
+ }, async ({ cnpj }) => handleCnpjValidate(cnpj)); // sem rate limit — é local
43
+ server.registerTool("cnpj_partners", {
44
+ description: "Lista sĂłcios (QSA) de uma empresa pelo CNPJ.",
45
+ inputSchema: { cnpj: z.string().describe("CNPJ da empresa") },
46
+ }, async ({ cnpj }) => withLimit(() => handleCnpjPartners(cnpj, cnpjService), "CNPJ"));
47
+ server.registerTool("cnpj_activities", {
48
+ description: "Retorna CNAEs (atividades econĂ´micas) de uma empresa pelo CNPJ.",
49
+ inputSchema: { cnpj: z.string().describe("CNPJ da empresa") },
50
+ }, async ({ cnpj }) => withLimit(() => handleCnpjActivities(cnpj, cnpjService), "CNPJ"));
51
+ server.registerTool("cnpj_address", {
52
+ description: "Retorna endereço registrado na Receita Federal para um CNPJ.",
53
+ inputSchema: { cnpj: z.string().describe("CNPJ da empresa") },
54
+ }, async ({ cnpj }) => withLimit(() => handleCnpjAddress(cnpj, cnpjService), "CNPJ"));
55
+ return { server, cnpjService, rateLimiter: limiter };
56
+ }
57
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { CnpjData } from "../types.js";
2
+ /**
3
+ * Formata os dados de uma empresa em relatĂłrio textual legĂ­vel.
4
+ */
5
+ export declare function formatCompanyReport(data: CnpjData): string;
6
+ /**
7
+ * Formata a lista de sĂłcios de uma empresa.
8
+ */
9
+ export declare function formatPartnersList(razaoSocial: string, cnpj: string, socios: CnpjData["socios"]): string;
10
+ /**
11
+ * Formata as atividades econĂ´micas de uma empresa.
12
+ */
13
+ export declare function formatActivities(razaoSocial: string, cnpj: string, principal: CnpjData["atividade_principal"], secundarias: CnpjData["atividades_secundarias"]): string;
14
+ /**
15
+ * Formata o endereço de uma empresa.
16
+ */
17
+ export declare function formatAddress(data: CnpjData): string;
@@ -0,0 +1,94 @@
1
+ import { formatCnpj } from "../utils/cnpj.js";
2
+ /**
3
+ * Formata os dados de uma empresa em relatĂłrio textual legĂ­vel.
4
+ */
5
+ export function formatCompanyReport(data) {
6
+ const lines = [
7
+ `Empresa: ${data.razao_social}`,
8
+ data.nome_fantasia ? `Nome Fantasia: ${data.nome_fantasia}` : "",
9
+ `CNPJ: ${formatCnpj(data.cnpj)}`,
10
+ `Situação: ${data.situacao_cadastral}`,
11
+ `Data Abertura: ${data.data_abertura}`,
12
+ `Natureza JurĂ­dica: ${data.natureza_juridica}`,
13
+ `Capital Social: R$ ${data.capital_social.toLocaleString("pt-BR", { minimumFractionDigits: 2 })}`,
14
+ data.porte ? `Porte: ${data.porte}` : "",
15
+ "",
16
+ "Endereço:",
17
+ ` ${[data.logradouro, data.numero ? `nÂş ${data.numero}` : "", data.complemento].filter(Boolean).join(", ")}`,
18
+ ` ${data.bairro} - ${data.municipio}/${data.uf}`,
19
+ ` CEP: ${data.cep}`,
20
+ "",
21
+ data.telefone ? `Telefone: ${data.telefone}` : "",
22
+ data.email ? `E-mail: ${data.email}` : "",
23
+ "",
24
+ `Atividade Principal: ${data.atividade_principal.codigo} - ${data.atividade_principal.descricao}`,
25
+ ];
26
+ if (data.atividades_secundarias.length > 0) {
27
+ lines.push(`Atividades Secundárias (${data.atividades_secundarias.length}):`, ...data.atividades_secundarias.map((a) => ` ${a.codigo} - ${a.descricao}`));
28
+ }
29
+ if (data.socios.length > 0) {
30
+ lines.push("", `SĂłcios (${data.socios.length}):`, ...data.socios.map((s) => ` - ${s.nome}${s.qualificacao ? ` (${s.qualificacao})` : ""}`));
31
+ }
32
+ return lines.filter((l) => l !== "").join("\n");
33
+ }
34
+ /**
35
+ * Formata a lista de sĂłcios de uma empresa.
36
+ */
37
+ export function formatPartnersList(razaoSocial, cnpj, socios) {
38
+ const lines = [
39
+ `SĂłcios de ${razaoSocial} (${formatCnpj(cnpj)}):`,
40
+ "",
41
+ ...socios.map((s, i) => {
42
+ const parts = [`${i + 1}. ${s.nome}`];
43
+ if (s.qualificacao)
44
+ parts.push(` Qualificação: ${s.qualificacao}`);
45
+ if (s.data_entrada)
46
+ parts.push(` Entrada: ${s.data_entrada}`);
47
+ return parts.join("\n");
48
+ }),
49
+ ];
50
+ return lines.join("\n");
51
+ }
52
+ /**
53
+ * Formata as atividades econĂ´micas de uma empresa.
54
+ */
55
+ export function formatActivities(razaoSocial, cnpj, principal, secundarias) {
56
+ const lines = [
57
+ `Atividades econĂ´micas de ${razaoSocial} (${formatCnpj(cnpj)}):`,
58
+ "",
59
+ `Atividade Principal:`,
60
+ ` ${principal.codigo} - ${principal.descricao}`,
61
+ ];
62
+ if (secundarias.length > 0) {
63
+ lines.push("", "Atividades Secundárias:");
64
+ secundarias.forEach((a) => {
65
+ lines.push(` ${a.codigo} - ${a.descricao}`);
66
+ });
67
+ }
68
+ return lines.join("\n");
69
+ }
70
+ /**
71
+ * Formata o endereço de uma empresa.
72
+ */
73
+ export function formatAddress(data) {
74
+ const addressParts = [
75
+ data.logradouro,
76
+ data.numero ? `nÂş ${data.numero}` : "",
77
+ data.complemento,
78
+ ]
79
+ .filter(Boolean)
80
+ .join(", ");
81
+ const lines = [
82
+ `Endereço de ${data.razao_social} (${formatCnpj(data.cnpj)}):`,
83
+ "",
84
+ addressParts,
85
+ `${data.bairro} - ${data.municipio}/${data.uf}`,
86
+ `CEP: ${data.cep}`,
87
+ ];
88
+ if (data.telefone)
89
+ lines.push(`Telefone: ${data.telefone}`);
90
+ if (data.email)
91
+ lines.push(`E-mail: ${data.email}`);
92
+ return lines.join("\n");
93
+ }
94
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/tools/format.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { CnpjService } from "../providers/index.js";
2
+ /** Tipo padrĂŁo de retorno dos handlers MCP. */
3
+ export interface ToolResult {
4
+ [key: string]: unknown;
5
+ content: Array<{
6
+ type: "text";
7
+ text: string;
8
+ }>;
9
+ }
10
+ export declare function handleCnpjLookup(cnpj: string, service: CnpjService): Promise<ToolResult>;
11
+ export declare function handleCnpjValidate(cnpj: string): Promise<ToolResult>;
12
+ export declare function handleCnpjPartners(cnpj: string, service: CnpjService): Promise<ToolResult>;
13
+ export declare function handleCnpjActivities(cnpj: string, service: CnpjService): Promise<ToolResult>;
14
+ export declare function handleCnpjAddress(cnpj: string, service: CnpjService): Promise<ToolResult>;
@@ -0,0 +1,77 @@
1
+ import { cleanCnpj, formatCnpj, isValidCnpj } from "../utils/cnpj.js";
2
+ import { formatCompanyReport, formatPartnersList, formatActivities, formatAddress, } from "./format.js";
3
+ function textResult(text) {
4
+ return { content: [{ type: "text", text }] };
5
+ }
6
+ function errorResult(prefix, err) {
7
+ const message = err instanceof Error ? err.message : String(err);
8
+ return textResult(`❌ ${prefix}: ${message}`);
9
+ }
10
+ // ─── cnpj_lookup ──────────────────────────────────────────
11
+ export async function handleCnpjLookup(cnpj, service) {
12
+ const clean = cleanCnpj(cnpj);
13
+ if (!isValidCnpj(clean)) {
14
+ return textResult(`❌ CNPJ inválido: ${cnpj}. Verifique se todos os dígitos estão corretos.`);
15
+ }
16
+ try {
17
+ const data = await service.lookup(clean);
18
+ return textResult(formatCompanyReport(data));
19
+ }
20
+ catch (err) {
21
+ return errorResult("Erro ao consultar CNPJ", err);
22
+ }
23
+ }
24
+ // ─── cnpj_validate ────────────────────────────────────────
25
+ export async function handleCnpjValidate(cnpj) {
26
+ const clean = cleanCnpj(cnpj);
27
+ const valid = isValidCnpj(clean);
28
+ return textResult(valid
29
+ ? `✅ CNPJ ${formatCnpj(clean)} é válido (dígitos verificadores corretos).`
30
+ : `❌ CNPJ ${cnpj} é inválido. Os dígitos verificadores não conferem.`);
31
+ }
32
+ // ─── cnpj_partners ────────────────────────────────────────
33
+ export async function handleCnpjPartners(cnpj, service) {
34
+ const clean = cleanCnpj(cnpj);
35
+ if (!isValidCnpj(clean)) {
36
+ return textResult(`❌ CNPJ inválido: ${cnpj}`);
37
+ }
38
+ try {
39
+ const data = await service.lookup(clean);
40
+ if (!data.socios || data.socios.length === 0) {
41
+ return textResult(`Nenhum sĂłcio encontrado para ${formatCnpj(clean)} (${data.razao_social}).`);
42
+ }
43
+ return textResult(formatPartnersList(data.razao_social, clean, data.socios));
44
+ }
45
+ catch (err) {
46
+ return errorResult("Erro", err);
47
+ }
48
+ }
49
+ // ─── cnpj_activities ──────────────────────────────────────
50
+ export async function handleCnpjActivities(cnpj, service) {
51
+ const clean = cleanCnpj(cnpj);
52
+ if (!isValidCnpj(clean)) {
53
+ return textResult(`❌ CNPJ inválido: ${cnpj}`);
54
+ }
55
+ try {
56
+ const data = await service.lookup(clean);
57
+ return textResult(formatActivities(data.razao_social, clean, data.atividade_principal, data.atividades_secundarias));
58
+ }
59
+ catch (err) {
60
+ return errorResult("Erro", err);
61
+ }
62
+ }
63
+ // ─── cnpj_address ─────────────────────────────────────────
64
+ export async function handleCnpjAddress(cnpj, service) {
65
+ const clean = cleanCnpj(cnpj);
66
+ if (!isValidCnpj(clean)) {
67
+ return textResult(`❌ CNPJ inválido: ${cnpj}`);
68
+ }
69
+ try {
70
+ const data = await service.lookup(clean);
71
+ return textResult(formatAddress(data));
72
+ }
73
+ catch (err) {
74
+ return errorResult("Erro", err);
75
+ }
76
+ }
77
+ //# sourceMappingURL=handlers.js.map