Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,16 @@ but the few rules below hold everywhere:
argument is an options object, which therefore never read stdin on their own. All three types
are derived from the public signatures, so `npm run check` fails when a new non-string option or
argument, or a new params-only utility, is missing from them.
- `src/_mcp/` is the `brazilian-utils-mcp` server (a `bin` of `package.json`), laid out like
`src/_internals/`: one function per folder. It serves the Model Context Protocol over stdio, so
an agent calls the library instead of answering from memory. `handle-message` is the protocol as
a pure function (one decoded JSON-RPC message in, one response out), `serve-stdio` connects it
to a pair of streams, `call-tool` and `parse-tool-arguments` check a call against the tool's
JSON Schema and run it, and `brazilian-utils-mcp.ts` is the Node.js entry, built into
`dist/brazilian-utils-mcp.js` by its own pack config in `vite.config.ts` with the library left
external. No library entry point imports it, so it never reaches a consumer's bundle. The tools
are the table in `src/_mcp/constants.ts`, one per public function: a test compares it with
`src/index.ts`, so `npm run test` fails when a new utility has no tool.
- There are no runtime dependencies (see [Zero runtime dependencies](#zero-runtime-dependencies)),
so the trust boundary of the published package is this repository, its build toolchain and the
npm registry; [MAINTAINERS.md](MAINTAINERS.md) lists who can change what, and
Expand Down Expand Up @@ -147,6 +157,10 @@ example `formatSomething`):
alphabetical ordering. Then add the function name to the `PUBLIC` list and the type(s) to the
`publicTypes` map in `src/index.test.ts`, alphabetically. These two make up the package's
public surface contract, and the test suite fails the build if either is out of sync.
Then add the tool that exposes it to agents to `TOOLS` in `src/_mcp/constants.ts`, also
alphabetically: the name of the function, a description written for a model, the JSON Schema of
its arguments and the properties to pass positionally. `src/_mcp/call-tool/call-tool.test.ts`
compares the table with `src/index.ts` and fails when a utility has no tool.
5. Document the utility in **both**:
- `docs/utilities.md` (English)
- `docs/pt-br/utilities.md` (Portuguese translation)
Expand Down
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
- [Installation](#installation)
- [Runtime support](#runtime-support)
- [Usage](#usage)
- [MCP server](#mcp-server)
- [Development](#development)
- [Contributors](#contributors)
- [License](#license)
Expand Down Expand Up @@ -113,6 +114,23 @@ echo 01001000 | npx @brazilian-utils/brazilian-utils getAddressInfoByCep # rea

The first argument is the name of a utility, the positional values are its arguments and `--key value`, `--flag` or `--json '<object>'` become its options object. `list` prints every utility and `--help` the full usage. See [Command line](https://brazilian-utils.com.br/getting-started?id=command-line).

## MCP server

The package also ships `brazilian-utils-mcp`, a [Model Context Protocol](https://modelcontextprotocol.io) server that hands every util to an agent as a tool, so it validates a CPF or reads a boleto by calling the library instead of answering from memory. Add it to Claude Desktop, Claude Code, Cursor or any other MCP client:

```json
{
"mcpServers": {
"brazilian-utils": {
"command": "npx",
"args": ["-y", "--package=@brazilian-utils/brazilian-utils", "brazilian-utils-mcp"]
}
}
}
```

It speaks stdio, implements revision 2026-07-28 of the specification and falls back to the `initialize` handshake of the older ones, and has no dependencies of its own. See [MCP server](https://brazilian-utils.com.br/getting-started?id=mcp-server).

## Development

This repository uses Vite+ as the local toolchain; it is installed as a dependency, so nothing has
Expand Down
29 changes: 28 additions & 1 deletion docs/getting-started.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: "Getting Started"
description: "Install Brazilian Utils, the zero-dependency utils library for Brazilian businesses, and learn how to import a util, which runtimes are supported and how the bundle size behaves."
keywords: ["Brazilian Utils", "install", "npm", "tree-shaking", "bundle size", "subpath imports", "Node.js", "Bun", "Deno", "browser", "AI assistants", "Context7"]
keywords: ["Brazilian Utils", "install", "npm", "tree-shaking", "bundle size", "subpath imports", "Node.js", "Bun", "Deno", "browser", "AI assistants", "Context7", "MCP"]
---

Brazilian Utils is a library focused on solving problems that we face daily in the development of applications for the Brazilian business.
Expand Down Expand Up @@ -120,6 +120,33 @@ To stop repeating it, add the rule to the agent's instructions file (`CLAUDE.md`

Without Context7, point the assistant at [llms.txt](https://brazilian-utils.com.br/llms.txt), which lists every util with a one-line description and a link to its section, or at [llms-full.txt](https://brazilian-utils.com.br/llms-full.txt), the whole English documentation in one Markdown file.

## MCP server

The package also ships `brazilian-utils-mcp`, a [Model Context Protocol](https://modelcontextprotocol.io) server that hands every util to an agent as a tool. The agent then validates a CPF, reads a boleto or looks an IBGE municipality up by calling the library, instead of answering from memory:

```bash
npx -y --package=@brazilian-utils/brazilian-utils brazilian-utils-mcp
```

It is a local server over stdio, so it goes in the client's configuration file the way any other one does. The same block works in Claude Desktop (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS, `%APPDATA%\Claude\claude_desktop_config.json` on Windows), in Claude Code (`.mcp.json` at the root of the project) and in Cursor (`.cursor/mcp.json` in the project, or `~/.cursor/mcp.json` for every project):

```json
{
"mcpServers": {
"brazilian-utils": {
"command": "npx",
"args": ["-y", "--package=@brazilian-utils/brazilian-utils", "brazilian-utils-mcp"]
}
}
}
```

In Claude Code, `claude mcp add brazilian-utils -- npx -y --package=@brazilian-utils/brazilian-utils brazilian-utils-mcp` writes that file for you. Restart the client, and a prompt such as "is 111.444.777-35 a valid CPF, and which holidays does São Paulo have in 2026?" reaches the tools.

There is one tool per util, named exactly as the function is exported (`isValidCpf`, `formatCnpj`, `getHolidays`), taking the same arguments and answering with its result as JSON. Documents are passed as strings, so leading zeros survive, and dates are written `YYYY-MM-DD`. An invalid value is an ordinary answer, not a failure: validators answer `false`, formatters and parsers `""`, lookups `null`. Everything is computed offline from the embedded datasets, `getAddressInfoByCep` and `getCepInfoByAddress` aside, the only two tools that reach the network.

The server implements revision [2026-07-28](https://modelcontextprotocol.io/specification/2026-07-28) of the specification, which negotiates the protocol version per request, and falls back to the `initialize` handshake of the older revisions, from 2025-11-25 down to 2024-11-05, for clients that speak one of those. It has no dependencies of its own: the stdio transport and the JSON-RPC surface ship with the package. Like the library, it is a separate file that no entry point imports, so it adds nothing to your bundle.

## Bundle size

The package is tree-shakeable: importing one util from the root pulls in only that util's code, not the rest of the library. `isValidCpf`, for example, adds roughly 1.4 KB minified (0.8 KB gzipped) to your bundle. A bundler that supports tree-shaking (webpack, Rollup, esbuild, Vite, etc.) drops every other util.
Expand Down
28 changes: 28 additions & 0 deletions docs/llms-full.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
- [Usage](#usage)
- [Command line](#command-line)
- [AI assistants](#ai-assistants)
- [MCP server](#mcp-server)
- [Bundle size](#bundle-size)
- [Utilities](#utilities)
- [isValidCpf](#isvalidcpf)
Expand Down Expand Up @@ -270,6 +271,33 @@ To stop repeating it, add the rule to the agent's instructions file (`CLAUDE.md`

Without Context7, point the assistant at [llms.txt](https://brazilian-utils.com.br/llms.txt), which lists every util with a one-line description and a link to its section, or at [llms-full.txt](https://brazilian-utils.com.br/llms-full.txt), the whole English documentation in one Markdown file.

### MCP server

The package also ships `brazilian-utils-mcp`, a [Model Context Protocol](https://modelcontextprotocol.io) server that hands every util to an agent as a tool. The agent then validates a CPF, reads a boleto or looks an IBGE municipality up by calling the library, instead of answering from memory:

```bash
npx -y --package=@brazilian-utils/brazilian-utils brazilian-utils-mcp
```

It is a local server over stdio, so it goes in the client's configuration file the way any other one does. The same block works in Claude Desktop (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS, `%APPDATA%\Claude\claude_desktop_config.json` on Windows), in Claude Code (`.mcp.json` at the root of the project) and in Cursor (`.cursor/mcp.json` in the project, or `~/.cursor/mcp.json` for every project):

```json
{
"mcpServers": {
"brazilian-utils": {
"command": "npx",
"args": ["-y", "--package=@brazilian-utils/brazilian-utils", "brazilian-utils-mcp"]
}
}
}
```

In Claude Code, `claude mcp add brazilian-utils -- npx -y --package=@brazilian-utils/brazilian-utils brazilian-utils-mcp` writes that file for you. Restart the client, and a prompt such as "is 111.444.777-35 a valid CPF, and which holidays does São Paulo have in 2026?" reaches the tools.

There is one tool per util, named exactly as the function is exported (`isValidCpf`, `formatCnpj`, `getHolidays`), taking the same arguments and answering with its result as JSON. Documents are passed as strings, so leading zeros survive, and dates are written `YYYY-MM-DD`. An invalid value is an ordinary answer, not a failure: validators answer `false`, formatters and parsers `""`, lookups `null`. Everything is computed offline from the embedded datasets, `getAddressInfoByCep` and `getCepInfoByAddress` aside, the only two tools that reach the network.

The server implements revision [2026-07-28](https://modelcontextprotocol.io/specification/2026-07-28) of the specification, which negotiates the protocol version per request, and falls back to the `initialize` handshake of the older revisions, from 2025-11-25 down to 2024-11-05, for clients that speak one of those. It has no dependencies of its own: the stdio transport and the JSON-RPC surface ship with the package. Like the library, it is a separate file that no entry point imports, so it adds nothing to your bundle.

### Bundle size

The package is tree-shakeable: importing one util from the root pulls in only that util's code, not the rest of the library. `isValidCpf`, for example, adds roughly 1.4 KB minified (0.8 KB gzipped) to your bundle. A bundler that supports tree-shaking (webpack, Rollup, esbuild, Vite, etc.) drops every other util.
Expand Down
29 changes: 28 additions & 1 deletion docs/pt-br/getting-started.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: "Introdução"
description: "Instale o Brazilian Utils, a biblioteca de utilitários sem dependências para o business brasileiro, e veja como importar um utilitário, quais runtimes são suportados e como o tamanho do bundle se comporta."
keywords: ["Brazilian Utils", "instalação", "npm", "tree-shaking", "tamanho do bundle", "subpath", "Node.js", "Bun", "Deno", "navegador", "assistentes de IA", "Context7"]
keywords: ["Brazilian Utils", "instalação", "npm", "tree-shaking", "tamanho do bundle", "subpath", "Node.js", "Bun", "Deno", "navegador", "assistentes de IA", "Context7", "MCP"]
---

Brazilian Utils é uma biblioteca com foco na resolução de problemas que enfrentamos diariamente no desenvolvimento de aplicações para o business brasileiro.
Expand Down Expand Up @@ -120,6 +120,33 @@ Para não repetir isso a cada prompt, coloque a regra no arquivo de instruções

Sem o Context7, aponte o assistente para o [llms.txt](https://brazilian-utils.com.br/llms.txt), que lista todos os utilitários com uma descrição de uma linha e o link para a seção de cada um, ou para o [llms-full.txt](https://brazilian-utils.com.br/llms-full.txt), a documentação completa em inglês em um único arquivo Markdown.

## Servidor MCP

O pacote também traz o `brazilian-utils-mcp`, um servidor [Model Context Protocol](https://modelcontextprotocol.io) que entrega cada utilitário ao agente como uma ferramenta. Assim o agente valida um CPF, lê um boleto ou busca um município do IBGE chamando a biblioteca, em vez de responder de memória:

```bash
npx -y --package=@brazilian-utils/brazilian-utils brazilian-utils-mcp
```

É um servidor local, que fala por stdio, então entra no arquivo de configuração do cliente como qualquer outro. O mesmo bloco funciona no Claude Desktop (`~/Library/Application Support/Claude/claude_desktop_config.json` no macOS, `%APPDATA%\Claude\claude_desktop_config.json` no Windows), no Claude Code (`.mcp.json` na raiz do projeto) e no Cursor (`.cursor/mcp.json` no projeto, ou `~/.cursor/mcp.json` para todos eles):

```json
{
"mcpServers": {
"brazilian-utils": {
"command": "npx",
"args": ["-y", "--package=@brazilian-utils/brazilian-utils", "brazilian-utils-mcp"]
}
}
}
```

No Claude Code, `claude mcp add brazilian-utils -- npx -y --package=@brazilian-utils/brazilian-utils brazilian-utils-mcp` escreve esse arquivo para você. Reinicie o cliente e um prompt como "111.444.777-35 é um CPF válido? E quais são os feriados de São Paulo em 2026?" chega às ferramentas.

Há uma ferramenta por utilitário, com o mesmo nome da função exportada (`isValidCpf`, `formatCnpj`, `getHolidays`), que recebe os mesmos argumentos e responde com o resultado em JSON. Documentos são passados como texto, para que os zeros à esquerda sobrevivam, e datas são escritas como `YYYY-MM-DD`. Um valor inválido é uma resposta comum, não uma falha: validadores respondem `false`, formatadores e parsers `""`, buscas `null`. Tudo é calculado offline, a partir dos datasets embutidos, com exceção de `getAddressInfoByCep` e `getCepInfoByAddress`, as duas únicas ferramentas que acessam a rede.

O servidor implementa a revisão [2026-07-28](https://modelcontextprotocol.io/specification/2026-07-28) da especificação, que negocia a versão do protocolo a cada requisição, e volta para o handshake `initialize` das revisões anteriores, da 2025-11-25 até a 2024-11-05, para os clientes que falam uma delas. Ele não tem dependências próprias: o transporte stdio e a superfície JSON-RPC vêm no pacote. Como a biblioteca, é um arquivo separado que nenhum entry point importa, então não adiciona nada ao seu bundle.

## Tamanho do bundle

O pacote é tree-shakeable: importar um utilitário da raiz traz apenas o código daquele utilitário, não o resto da biblioteca. `isValidCpf`, por exemplo, adiciona cerca de 1,4 KB minificado (0,8 KB com gzip) ao seu bundle. Um bundler com suporte a tree-shaking (webpack, Rollup, esbuild, Vite, etc.) descarta todos os outros utilitários.
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@
"url": "git+https://github.com/brazilian-utils/javascript.git"
},
"bin": {
"brazilian-utils": "./dist/cli.js"
"brazilian-utils": "./dist/cli.js",
"brazilian-utils-mcp": "./dist/brazilian-utils-mcp.js"
},
Comment thread
coderabbitai[bot] marked this conversation as resolved.
"files": [
"./CHANGELOG.md",
Expand Down Expand Up @@ -88,6 +89,7 @@
}
},
"./cli": null,
"./brazilian-utils-mcp": null,
"./*": {
"import": {
"types": "./dist/*.d.ts",
Expand Down
Loading
Loading