@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 +75 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/providers/brasil-api.d.ts +11 -0
- package/dist/providers/brasil-api.js +69 -0
- package/dist/providers/brasil-api.js.map +1 -0
- package/dist/providers/index.d.ts +19 -0
- package/dist/providers/index.js +56 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/receita-ws.d.ts +12 -0
- package/dist/providers/receita-ws.js +66 -0
- package/dist/providers/receita-ws.js.map +1 -0
- package/dist/server.d.ts +16 -0
- package/dist/server.js +57 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/format.d.ts +17 -0
- package/dist/tools/format.js +94 -0
- package/dist/tools/format.js.map +1 -0
- package/dist/tools/handlers.d.ts +14 -0
- package/dist/tools/handlers.js +77 -0
- package/dist/tools/handlers.js.map +1 -0
- package/dist/types.d.ts +52 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/cache.d.ts +19 -0
- package/dist/utils/cache.js +53 -0
- package/dist/utils/cache.js.map +1 -0
- package/dist/utils/cnpj.d.ts +21 -0
- package/dist/utils/cnpj.js +66 -0
- package/dist/utils/cnpj.js.map +1 -0
- package/dist/utils/rate-limiter.d.ts +88 -0
- package/dist/utils/rate-limiter.js +263 -0
- package/dist/utils/rate-limiter.js.map +1 -0
- package/package.json +52 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handlers.js","sourceRoot":"","sources":["../../src/tools/handlers.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sócio/QSA de uma empresa.
|
|
3
|
+
*/
|
|
4
|
+
export interface CnpjPartner {
|
|
5
|
+
nome: string;
|
|
6
|
+
qualificacao: string;
|
|
7
|
+
data_entrada?: string;
|
|
8
|
+
cpf_cnpj?: string;
|
|
9
|
+
faixa_etaria?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Atividade econômica (CNAE).
|
|
13
|
+
*/
|
|
14
|
+
export interface CnpjActivity {
|
|
15
|
+
codigo: string;
|
|
16
|
+
descricao: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Dados completos de um CNPJ.
|
|
20
|
+
* Normalizado para formato único independente do provider.
|
|
21
|
+
*/
|
|
22
|
+
export interface CnpjData {
|
|
23
|
+
cnpj: string;
|
|
24
|
+
razao_social: string;
|
|
25
|
+
nome_fantasia: string;
|
|
26
|
+
situacao_cadastral: string;
|
|
27
|
+
data_situacao_cadastral: string;
|
|
28
|
+
data_abertura: string;
|
|
29
|
+
natureza_juridica: string;
|
|
30
|
+
capital_social: number;
|
|
31
|
+
porte: string;
|
|
32
|
+
tipo: string;
|
|
33
|
+
logradouro: string;
|
|
34
|
+
numero: string;
|
|
35
|
+
complemento: string;
|
|
36
|
+
bairro: string;
|
|
37
|
+
municipio: string;
|
|
38
|
+
uf: string;
|
|
39
|
+
cep: string;
|
|
40
|
+
telefone: string;
|
|
41
|
+
email: string;
|
|
42
|
+
atividade_principal: CnpjActivity;
|
|
43
|
+
atividades_secundarias: CnpjActivity[];
|
|
44
|
+
socios: CnpjPartner[];
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Interface para providers de dados CNPJ.
|
|
48
|
+
*/
|
|
49
|
+
export interface CnpjProvider {
|
|
50
|
+
name: string;
|
|
51
|
+
fetchCnpj(cnpj: string): Promise<CnpjData>;
|
|
52
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cache em memória com TTL por chave.
|
|
3
|
+
* Sem dependências externas — Map nativo.
|
|
4
|
+
*/
|
|
5
|
+
export declare class MemoryCache<T = unknown> {
|
|
6
|
+
private store;
|
|
7
|
+
private defaultTtlMs;
|
|
8
|
+
constructor(defaultTtlMs?: number);
|
|
9
|
+
get(key: string): T | null;
|
|
10
|
+
set(key: string, data: T, ttlMs?: number): void;
|
|
11
|
+
delete(key: string): boolean;
|
|
12
|
+
clear(): void;
|
|
13
|
+
get size(): number;
|
|
14
|
+
/**
|
|
15
|
+
* Remove todas as entradas expiradas.
|
|
16
|
+
* Útil para manutenção periódica em servers de longa duração.
|
|
17
|
+
*/
|
|
18
|
+
prune(): number;
|
|
19
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cache em memória com TTL por chave.
|
|
3
|
+
* Sem dependências externas — Map nativo.
|
|
4
|
+
*/
|
|
5
|
+
export class MemoryCache {
|
|
6
|
+
store = new Map();
|
|
7
|
+
defaultTtlMs;
|
|
8
|
+
constructor(defaultTtlMs = 86_400_000) {
|
|
9
|
+
// Default: 24 horas
|
|
10
|
+
this.defaultTtlMs = defaultTtlMs;
|
|
11
|
+
}
|
|
12
|
+
get(key) {
|
|
13
|
+
const entry = this.store.get(key);
|
|
14
|
+
if (!entry)
|
|
15
|
+
return null;
|
|
16
|
+
if (Date.now() > entry.expiry) {
|
|
17
|
+
this.store.delete(key);
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
return entry.data;
|
|
21
|
+
}
|
|
22
|
+
set(key, data, ttlMs) {
|
|
23
|
+
this.store.set(key, {
|
|
24
|
+
data,
|
|
25
|
+
expiry: Date.now() + (ttlMs ?? this.defaultTtlMs),
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
delete(key) {
|
|
29
|
+
return this.store.delete(key);
|
|
30
|
+
}
|
|
31
|
+
clear() {
|
|
32
|
+
this.store.clear();
|
|
33
|
+
}
|
|
34
|
+
get size() {
|
|
35
|
+
return this.store.size;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Remove todas as entradas expiradas.
|
|
39
|
+
* Útil para manutenção periódica em servers de longa duração.
|
|
40
|
+
*/
|
|
41
|
+
prune() {
|
|
42
|
+
const now = Date.now();
|
|
43
|
+
let pruned = 0;
|
|
44
|
+
for (const [key, entry] of this.store) {
|
|
45
|
+
if (now > entry.expiry) {
|
|
46
|
+
this.store.delete(key);
|
|
47
|
+
pruned++;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return pruned;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/utils/cache.ts"],"names":[],"mappings":"AAKA;;;GAGG;AACH,MAAM,OAAO,WAAW;IACd,KAAK,GAAG,IAAI,GAAG,EAAyB,CAAC;IACzC,YAAY,CAAS;IAE7B,YAAY,YAAY,GAAG,UAAU;QACnC,oBAAoB;QACpB,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACnC,CAAC;IAED,GAAG,CAAC,GAAW;QACb,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QAExB,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;YAC9B,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,KAAK,CAAC,IAAI,CAAC;IACpB,CAAC;IAED,GAAG,CAAC,GAAW,EAAE,IAAO,EAAE,KAAc;QACtC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE;YAClB,IAAI;YACJ,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,IAAI,IAAI,CAAC,YAAY,CAAC;SAClD,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CAAC,GAAW;QAChB,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC;IAED,KAAK;QACH,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;IACzB,CAAC;IAED;;;OAGG;IACH,KAAK;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACtC,IAAI,GAAG,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;gBACvB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBACvB,MAAM,EAAE,CAAC;YACX,CAAC;QACH,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Remove caracteres não-numéricos de um CNPJ.
|
|
3
|
+
*/
|
|
4
|
+
export declare function cleanCnpj(cnpj: string): string;
|
|
5
|
+
/**
|
|
6
|
+
* Formata um CNPJ limpo (14 dígitos) no padrão XX.XXX.XXX/XXXX-XX.
|
|
7
|
+
*/
|
|
8
|
+
export declare function formatCnpj(cnpj: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Valida se um CNPJ é matematicamente válido (dígitos verificadores).
|
|
11
|
+
* Não consulta a Receita Federal — apenas validação local.
|
|
12
|
+
*/
|
|
13
|
+
export declare function isValidCnpj(cnpj: string): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Remove caracteres não-numéricos de um CPF.
|
|
16
|
+
*/
|
|
17
|
+
export declare function cleanCpf(cpf: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* Valida se um CPF é matematicamente válido.
|
|
20
|
+
*/
|
|
21
|
+
export declare function isValidCpf(cpf: string): boolean;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Remove caracteres não-numéricos de um CNPJ.
|
|
3
|
+
*/
|
|
4
|
+
export function cleanCnpj(cnpj) {
|
|
5
|
+
return cnpj.replace(/\D/g, "");
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Formata um CNPJ limpo (14 dígitos) no padrão XX.XXX.XXX/XXXX-XX.
|
|
9
|
+
*/
|
|
10
|
+
export function formatCnpj(cnpj) {
|
|
11
|
+
const clean = cleanCnpj(cnpj);
|
|
12
|
+
if (clean.length !== 14)
|
|
13
|
+
return cnpj;
|
|
14
|
+
return clean.replace(/^(\d{2})(\d{3})(\d{3})(\d{4})(\d{2})$/, "$1.$2.$3/$4-$5");
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Valida se um CNPJ é matematicamente válido (dígitos verificadores).
|
|
18
|
+
* Não consulta a Receita Federal — apenas validação local.
|
|
19
|
+
*/
|
|
20
|
+
export function isValidCnpj(cnpj) {
|
|
21
|
+
const clean = cleanCnpj(cnpj);
|
|
22
|
+
if (clean.length !== 14)
|
|
23
|
+
return false;
|
|
24
|
+
// Rejeita CNPJs com todos os dígitos iguais (ex: 11.111.111/1111-11)
|
|
25
|
+
if (/^(\d)\1+$/.test(clean))
|
|
26
|
+
return false;
|
|
27
|
+
const calcDigit = (slice, weights) => {
|
|
28
|
+
const sum = slice
|
|
29
|
+
.split("")
|
|
30
|
+
.reduce((acc, digit, i) => acc + Number(digit) * weights[i], 0);
|
|
31
|
+
const remainder = sum % 11;
|
|
32
|
+
return remainder < 2 ? 0 : 11 - remainder;
|
|
33
|
+
};
|
|
34
|
+
const weights1 = [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2];
|
|
35
|
+
const weights2 = [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2];
|
|
36
|
+
const digit1 = calcDigit(clean.slice(0, 12), weights1);
|
|
37
|
+
const digit2 = calcDigit(clean.slice(0, 13), weights2);
|
|
38
|
+
return Number(clean[12]) === digit1 && Number(clean[13]) === digit2;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Remove caracteres não-numéricos de um CPF.
|
|
42
|
+
*/
|
|
43
|
+
export function cleanCpf(cpf) {
|
|
44
|
+
return cpf.replace(/\D/g, "");
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Valida se um CPF é matematicamente válido.
|
|
48
|
+
*/
|
|
49
|
+
export function isValidCpf(cpf) {
|
|
50
|
+
const clean = cleanCpf(cpf);
|
|
51
|
+
if (clean.length !== 11)
|
|
52
|
+
return false;
|
|
53
|
+
if (/^(\d)\1+$/.test(clean))
|
|
54
|
+
return false;
|
|
55
|
+
const calcDigit = (slice, factor) => {
|
|
56
|
+
const sum = slice
|
|
57
|
+
.split("")
|
|
58
|
+
.reduce((acc, digit, i) => acc + Number(digit) * (factor - i), 0);
|
|
59
|
+
const remainder = sum % 11;
|
|
60
|
+
return remainder < 2 ? 0 : 11 - remainder;
|
|
61
|
+
};
|
|
62
|
+
const digit1 = calcDigit(clean.slice(0, 9), 10);
|
|
63
|
+
const digit2 = calcDigit(clean.slice(0, 10), 11);
|
|
64
|
+
return Number(clean[9]) === digit1 && Number(clean[10]) === digit2;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=cnpj.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cnpj.js","sourceRoot":"","sources":["../../src/utils/cnpj.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interface para backends de armazenamento de contagem de chamadas do rate limiter.
|
|
3
|
+
*/
|
|
4
|
+
export interface RateLimiterStore {
|
|
5
|
+
readonly type: "memory" | "redis";
|
|
6
|
+
/**
|
|
7
|
+
* Tenta consumir 1 unidade de rate limit para a chave no dia informado.
|
|
8
|
+
* Retorna a contagem atual após o incremento.
|
|
9
|
+
*/
|
|
10
|
+
increment(key: string, day: string, ttlSeconds: number): Promise<number> | number;
|
|
11
|
+
/** Retorna a contagem atual sem incrementar. */
|
|
12
|
+
get(key: string, day: string): Promise<number> | number;
|
|
13
|
+
/** Reseta o armazenamento. */
|
|
14
|
+
reset(): Promise<void> | void;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Armazenamento em memória local (Map).
|
|
18
|
+
* Síncrono e ideal para servidores locais (CLI, NPM Free).
|
|
19
|
+
*/
|
|
20
|
+
export declare class MemoryRateLimiterStore implements RateLimiterStore {
|
|
21
|
+
readonly type: "memory";
|
|
22
|
+
private counts;
|
|
23
|
+
increment(key: string, day: string): number;
|
|
24
|
+
get(key: string, day: string): number;
|
|
25
|
+
reset(): void;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Armazenamento distribuído via Redis.
|
|
29
|
+
* Suporta Upstash / MCPize REST API via fetch nativo ou clientes TCP (ioredis / node-redis).
|
|
30
|
+
* Possui resiliência integrada: em caso de falha no Redis, faz fallback automático para memória.
|
|
31
|
+
*/
|
|
32
|
+
export declare class RedisRateLimiterStore implements RateLimiterStore {
|
|
33
|
+
readonly type: "redis";
|
|
34
|
+
private fallbackMemory;
|
|
35
|
+
private redisClient;
|
|
36
|
+
private clientPromise;
|
|
37
|
+
private isRest;
|
|
38
|
+
private restUrl?;
|
|
39
|
+
private restToken?;
|
|
40
|
+
private redisUrl?;
|
|
41
|
+
constructor(opts?: {
|
|
42
|
+
restUrl?: string;
|
|
43
|
+
restToken?: string;
|
|
44
|
+
redisUrl?: string;
|
|
45
|
+
});
|
|
46
|
+
private getClient;
|
|
47
|
+
increment(key: string, day: string, ttlSeconds: number): Promise<number>;
|
|
48
|
+
get(key: string, day: string): Promise<number>;
|
|
49
|
+
reset(): Promise<void>;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Detecta o backend de armazenamento mais apropriado baseado nas variáveis de ambiente.
|
|
53
|
+
*/
|
|
54
|
+
export declare function detectRateLimiterStoreFromEnv(): RateLimiterStore;
|
|
55
|
+
/**
|
|
56
|
+
* Rate limiter por dia para os pacotes free ou deploy gerenciado.
|
|
57
|
+
* Armazena contagem em memória ou no Redis (detectado por variáveis de ambiente ou configurado via store).
|
|
58
|
+
*/
|
|
59
|
+
export declare class DailyRateLimiter {
|
|
60
|
+
private store;
|
|
61
|
+
private maxPerDay;
|
|
62
|
+
constructor(maxPerDayOrOpts?: number | {
|
|
63
|
+
maxPerDay?: number;
|
|
64
|
+
store?: RateLimiterStore;
|
|
65
|
+
});
|
|
66
|
+
private today;
|
|
67
|
+
/**
|
|
68
|
+
* Tenta consumir um request. Retorna true se permitido, false se limitado.
|
|
69
|
+
* Se usando store em memória, retorna boolean síncrono. Se no Redis, retorna Promise<boolean>.
|
|
70
|
+
*/
|
|
71
|
+
tryConsume(key?: string): boolean | Promise<boolean>;
|
|
72
|
+
/**
|
|
73
|
+
* Retorna quantos requests restam hoje.
|
|
74
|
+
*/
|
|
75
|
+
remaining(key?: string): number | Promise<number>;
|
|
76
|
+
/**
|
|
77
|
+
* Retorna o limite diário configurado.
|
|
78
|
+
*/
|
|
79
|
+
get limit(): number;
|
|
80
|
+
/**
|
|
81
|
+
* Reseta a contagem (útil para testes).
|
|
82
|
+
*/
|
|
83
|
+
reset(): void | Promise<void>;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Mensagem padrão de upgrade quando o rate limit é atingido.
|
|
87
|
+
*/
|
|
88
|
+
export declare function rateLimitMessage(toolName: string, limit: number): string;
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Armazenamento em memória local (Map).
|
|
3
|
+
* Síncrono e ideal para servidores locais (CLI, NPM Free).
|
|
4
|
+
*/
|
|
5
|
+
export class MemoryRateLimiterStore {
|
|
6
|
+
type = "memory";
|
|
7
|
+
counts = new Map();
|
|
8
|
+
increment(key, day) {
|
|
9
|
+
const entry = this.counts.get(key);
|
|
10
|
+
if (!entry || entry.day !== day) {
|
|
11
|
+
this.counts.set(key, { count: 1, day });
|
|
12
|
+
return 1;
|
|
13
|
+
}
|
|
14
|
+
entry.count++;
|
|
15
|
+
return entry.count;
|
|
16
|
+
}
|
|
17
|
+
get(key, day) {
|
|
18
|
+
const entry = this.counts.get(key);
|
|
19
|
+
if (!entry || entry.day !== day)
|
|
20
|
+
return 0;
|
|
21
|
+
return entry.count;
|
|
22
|
+
}
|
|
23
|
+
reset() {
|
|
24
|
+
this.counts.clear();
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Armazenamento distribuído via Redis.
|
|
29
|
+
* Suporta Upstash / MCPize REST API via fetch nativo ou clientes TCP (ioredis / node-redis).
|
|
30
|
+
* Possui resiliência integrada: em caso de falha no Redis, faz fallback automático para memória.
|
|
31
|
+
*/
|
|
32
|
+
export class RedisRateLimiterStore {
|
|
33
|
+
type = "redis";
|
|
34
|
+
fallbackMemory = new MemoryRateLimiterStore();
|
|
35
|
+
redisClient = null;
|
|
36
|
+
clientPromise = null;
|
|
37
|
+
isRest;
|
|
38
|
+
restUrl;
|
|
39
|
+
restToken;
|
|
40
|
+
redisUrl;
|
|
41
|
+
constructor(opts) {
|
|
42
|
+
this.restUrl = opts?.restUrl ?? process.env.UPSTASH_REDIS_REST_URL ?? process.env.REDIS_REST_URL;
|
|
43
|
+
this.restToken = opts?.restToken ?? process.env.UPSTASH_REDIS_REST_TOKEN ?? process.env.REDIS_REST_TOKEN;
|
|
44
|
+
this.redisUrl = opts?.redisUrl ?? process.env.REDIS_URL ?? process.env.MCPIZE_REDIS_URL;
|
|
45
|
+
this.isRest = Boolean(this.restUrl && this.restToken);
|
|
46
|
+
}
|
|
47
|
+
async getClient() {
|
|
48
|
+
if (this.isRest)
|
|
49
|
+
return null;
|
|
50
|
+
if (this.redisClient)
|
|
51
|
+
return this.redisClient;
|
|
52
|
+
if (this.clientPromise)
|
|
53
|
+
return this.clientPromise;
|
|
54
|
+
this.clientPromise = (async () => {
|
|
55
|
+
try {
|
|
56
|
+
try {
|
|
57
|
+
// @ts-ignore
|
|
58
|
+
const ioredis = await import("ioredis");
|
|
59
|
+
const Redis = ioredis.default || ioredis.Redis || ioredis;
|
|
60
|
+
const client = this.redisUrl
|
|
61
|
+
? new Redis(this.redisUrl)
|
|
62
|
+
: new Redis({
|
|
63
|
+
host: process.env.REDIS_HOST || "localhost",
|
|
64
|
+
port: Number(process.env.REDIS_PORT || 6379),
|
|
65
|
+
password: process.env.REDIS_PASSWORD,
|
|
66
|
+
});
|
|
67
|
+
client.on("error", (err) => {
|
|
68
|
+
console.error(`[rate-limiter] Redis Client Error: ${err.message || err}`);
|
|
69
|
+
});
|
|
70
|
+
this.redisClient = client;
|
|
71
|
+
return client;
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
// @ts-ignore
|
|
75
|
+
const nodeRedis = await import("redis");
|
|
76
|
+
const createClient = nodeRedis.createClient || nodeRedis.default?.createClient;
|
|
77
|
+
if (createClient) {
|
|
78
|
+
const client = this.redisUrl
|
|
79
|
+
? createClient({ url: this.redisUrl })
|
|
80
|
+
: createClient({
|
|
81
|
+
socket: {
|
|
82
|
+
host: process.env.REDIS_HOST || "localhost",
|
|
83
|
+
port: Number(process.env.REDIS_PORT || 6379),
|
|
84
|
+
},
|
|
85
|
+
password: process.env.REDIS_PASSWORD,
|
|
86
|
+
});
|
|
87
|
+
client.on("error", (err) => {
|
|
88
|
+
console.error(`[rate-limiter] node-redis Client Error: ${err.message || err}`);
|
|
89
|
+
});
|
|
90
|
+
await client.connect();
|
|
91
|
+
this.redisClient = client;
|
|
92
|
+
return client;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
// Ignora caso nenhum driver Redis esteja instalado
|
|
98
|
+
}
|
|
99
|
+
return null;
|
|
100
|
+
})();
|
|
101
|
+
return this.clientPromise;
|
|
102
|
+
}
|
|
103
|
+
async increment(key, day, ttlSeconds) {
|
|
104
|
+
const redisKey = `ratelimit:${day}:${key}`;
|
|
105
|
+
if (this.isRest && this.restUrl && this.restToken) {
|
|
106
|
+
try {
|
|
107
|
+
const incrRes = await fetch(`${this.restUrl}/INCR/${encodeURIComponent(redisKey)}`, {
|
|
108
|
+
method: "POST",
|
|
109
|
+
headers: { Authorization: `Bearer ${this.restToken}` },
|
|
110
|
+
signal: AbortSignal.timeout(5000),
|
|
111
|
+
});
|
|
112
|
+
if (incrRes.ok) {
|
|
113
|
+
const data = await incrRes.json();
|
|
114
|
+
const count = Number(data.result || 1);
|
|
115
|
+
if (count === 1) {
|
|
116
|
+
await fetch(`${this.restUrl}/EXPIRE/${encodeURIComponent(redisKey)}/${ttlSeconds}`, {
|
|
117
|
+
method: "POST",
|
|
118
|
+
headers: { Authorization: `Bearer ${this.restToken}` },
|
|
119
|
+
signal: AbortSignal.timeout(5000),
|
|
120
|
+
}).catch(() => { });
|
|
121
|
+
}
|
|
122
|
+
return count;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
catch (err) {
|
|
126
|
+
console.error(`[rate-limiter] Redis REST falhou, usando fallback em memória: ${err instanceof Error ? err.message : err}`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
try {
|
|
130
|
+
const client = await this.getClient();
|
|
131
|
+
if (client && typeof client.incr === "function") {
|
|
132
|
+
const count = await client.incr(redisKey);
|
|
133
|
+
if (count === 1 && typeof client.expire === "function") {
|
|
134
|
+
await client.expire(redisKey, ttlSeconds);
|
|
135
|
+
}
|
|
136
|
+
return Number(count);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
catch (err) {
|
|
140
|
+
console.error(`[rate-limiter] Redis TCP falhou, usando fallback em memória: ${err instanceof Error ? err.message : err}`);
|
|
141
|
+
}
|
|
142
|
+
return this.fallbackMemory.increment(key, day);
|
|
143
|
+
}
|
|
144
|
+
async get(key, day) {
|
|
145
|
+
const redisKey = `ratelimit:${day}:${key}`;
|
|
146
|
+
if (this.isRest && this.restUrl && this.restToken) {
|
|
147
|
+
try {
|
|
148
|
+
const res = await fetch(`${this.restUrl}/GET/${encodeURIComponent(redisKey)}`, {
|
|
149
|
+
headers: { Authorization: `Bearer ${this.restToken}` },
|
|
150
|
+
signal: AbortSignal.timeout(5000),
|
|
151
|
+
});
|
|
152
|
+
if (res.ok) {
|
|
153
|
+
const data = await res.json();
|
|
154
|
+
return Number(data.result || 0);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
// Fallback
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
try {
|
|
162
|
+
const client = await this.getClient();
|
|
163
|
+
if (client && typeof client.get === "function") {
|
|
164
|
+
const val = await client.get(redisKey);
|
|
165
|
+
return Number(val || 0);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
catch {
|
|
169
|
+
// ignore
|
|
170
|
+
}
|
|
171
|
+
return this.fallbackMemory.get(key, day);
|
|
172
|
+
}
|
|
173
|
+
async reset() {
|
|
174
|
+
this.fallbackMemory.reset();
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Detecta o backend de armazenamento mais apropriado baseado nas variáveis de ambiente.
|
|
179
|
+
*/
|
|
180
|
+
export function detectRateLimiterStoreFromEnv() {
|
|
181
|
+
const hasRest = Boolean((process.env.UPSTASH_REDIS_REST_URL || process.env.REDIS_REST_URL) &&
|
|
182
|
+
(process.env.UPSTASH_REDIS_REST_TOKEN || process.env.REDIS_REST_TOKEN));
|
|
183
|
+
const hasTcp = Boolean(process.env.REDIS_URL ||
|
|
184
|
+
process.env.MCPIZE_REDIS_URL ||
|
|
185
|
+
process.env.REDIS_HOST);
|
|
186
|
+
if (hasRest || hasTcp) {
|
|
187
|
+
return new RedisRateLimiterStore();
|
|
188
|
+
}
|
|
189
|
+
return new MemoryRateLimiterStore();
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Rate limiter por dia para os pacotes free ou deploy gerenciado.
|
|
193
|
+
* Armazena contagem em memória ou no Redis (detectado por variáveis de ambiente ou configurado via store).
|
|
194
|
+
*/
|
|
195
|
+
export class DailyRateLimiter {
|
|
196
|
+
store;
|
|
197
|
+
maxPerDay;
|
|
198
|
+
constructor(maxPerDayOrOpts) {
|
|
199
|
+
if (typeof maxPerDayOrOpts === "number") {
|
|
200
|
+
this.maxPerDay = maxPerDayOrOpts;
|
|
201
|
+
this.store = detectRateLimiterStoreFromEnv();
|
|
202
|
+
}
|
|
203
|
+
else if (typeof maxPerDayOrOpts === "object" && maxPerDayOrOpts !== null) {
|
|
204
|
+
this.maxPerDay = maxPerDayOrOpts.maxPerDay ?? 50;
|
|
205
|
+
this.store = maxPerDayOrOpts.store ?? detectRateLimiterStoreFromEnv();
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
this.maxPerDay = 50;
|
|
209
|
+
this.store = detectRateLimiterStoreFromEnv();
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
today() {
|
|
213
|
+
return new Date().toISOString().split("T")[0];
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Tenta consumir um request. Retorna true se permitido, false se limitado.
|
|
217
|
+
* Se usando store em memória, retorna boolean síncrono. Se no Redis, retorna Promise<boolean>.
|
|
218
|
+
*/
|
|
219
|
+
tryConsume(key = "global") {
|
|
220
|
+
const day = this.today();
|
|
221
|
+
if (this.store.type === "memory") {
|
|
222
|
+
const current = this.store.increment(key, day, 86400);
|
|
223
|
+
return current <= this.maxPerDay;
|
|
224
|
+
}
|
|
225
|
+
return Promise.resolve(this.store.increment(key, day, 86400)).then((current) => current <= this.maxPerDay);
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Retorna quantos requests restam hoje.
|
|
229
|
+
*/
|
|
230
|
+
remaining(key = "global") {
|
|
231
|
+
const day = this.today();
|
|
232
|
+
if (this.store.type === "memory") {
|
|
233
|
+
const current = this.store.get(key, day);
|
|
234
|
+
return Math.max(0, this.maxPerDay - current);
|
|
235
|
+
}
|
|
236
|
+
return Promise.resolve(this.store.get(key, day)).then((current) => Math.max(0, this.maxPerDay - current));
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Retorna o limite diário configurado.
|
|
240
|
+
*/
|
|
241
|
+
get limit() {
|
|
242
|
+
return this.maxPerDay;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Reseta a contagem (útil para testes).
|
|
246
|
+
*/
|
|
247
|
+
reset() {
|
|
248
|
+
return this.store.reset();
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Mensagem padrão de upgrade quando o rate limit é atingido.
|
|
253
|
+
*/
|
|
254
|
+
export function rateLimitMessage(toolName, limit) {
|
|
255
|
+
return [
|
|
256
|
+
`⚠️ Limite diário atingido (${limit} consultas/dia no plano gratuito).`,
|
|
257
|
+
``,
|
|
258
|
+
`Para uso ilimitado de ${toolName} + Pix, NFe e WhatsApp:`,
|
|
259
|
+
`→ npm install @brazil-mcp/bundle-pro`,
|
|
260
|
+
`→ Ou acesse: https://mcpize.com/brazil-mcp`,
|
|
261
|
+
].join("\n");
|
|
262
|
+
}
|
|
263
|
+
//# sourceMappingURL=rate-limiter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-limiter.js","sourceRoot":"","sources":["../../src/utils/rate-limiter.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@brazil-mcp/cnpj",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MCP server para consulta de CNPJ, sócios e atividades de empresas brasileiras",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"cnpj-mcp": "./dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"main": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"files": [
|
|
12
|
+
"dist"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsc",
|
|
16
|
+
"dev": "tsx src/index.ts",
|
|
17
|
+
"inspect": "npx @modelcontextprotocol/inspector node dist/index.js",
|
|
18
|
+
"test": "vitest run tests/unit",
|
|
19
|
+
"test:watch": "vitest tests/unit",
|
|
20
|
+
"test:flow": "vitest run tests/flow",
|
|
21
|
+
"test:integration": "vitest run tests/integration",
|
|
22
|
+
"test:all": "vitest run tests/unit tests/flow",
|
|
23
|
+
"test:coverage": "vitest run tests/unit tests/flow --coverage"
|
|
24
|
+
},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"mcp",
|
|
27
|
+
"mcp-server",
|
|
28
|
+
"brazil",
|
|
29
|
+
"brasil",
|
|
30
|
+
"cnpj",
|
|
31
|
+
"empresa",
|
|
32
|
+
"receita-federal",
|
|
33
|
+
"consulta-cnpj"
|
|
34
|
+
],
|
|
35
|
+
"author": "Acauã",
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "https://github.com/acaua/brazil-mcp"
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
43
|
+
"zod": "^3.25.0"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@types/node": "^22.0.0",
|
|
47
|
+
"@vitest/coverage-v8": "^3.2.0",
|
|
48
|
+
"tsx": "^4.19.0",
|
|
49
|
+
"typescript": "^5.7.0",
|
|
50
|
+
"vitest": "^3.2.0"
|
|
51
|
+
}
|
|
52
|
+
}
|