Skip to main content
Glama
company-investigator-mcp

company-investigator-mcp

by CalebePrates

Company Investigator MCP

MCP server for public company intelligence, corporate relationships and evidence-based investigation.

CI PyPI npm Python MCP License

What

An MCP server that lets an LLM client (Claude, or any other MCP-compatible client) look up a Brazilian company by CNPJ or name, walk its corporate network, and pull together public evidence — official registry data, corporate relationships, news, social/LinkedIn profiles, public judicial proceedings and Politically Exposed Person (PEP) checks — into one structured, source-attributed result.

Looking up a company usually means checking half a dozen disconnected sources by hand and manually piecing together who runs it and what else they are involved in. This server does the collection:

Company/CNPJ → Partners → Related companies → Related people
  → News / LinkedIn / public profiles → Public proceedings → PEP
  → Relationship graph → Structured investigation (read in pages by the client)

The server collects and structures the evidence; it does not interpret it. Deciding what to dig into, cross-checking sources and writing the final analysis is the job of the MCP client / AI agent (Claude, a local Qwen, …). There is deliberately no LLM inside this server.

MCP Client / AI Agent → Company Investigator MCP → structured investigation
                      → MCP Client / AI Agent → analysis

Related MCP server: cnpj-br

Features

  • Company intelligence — official registry data (CNPJ, razão social, nome fantasia, status) via BrasilAPI.

  • Corporate relationships — discovers other companies a partner is associated with, and expands the network to a configurable depth (0–2).

  • People intelligence — partners, administrators and LinkedIn key people (CEO, founders, directors and other leadership roles).

  • News and public sources — public mentions of the company, each with title, URL, source and confidence.

  • LinkedIn / social profiles — company page and key people on LinkedIn, plus Instagram, Facebook, YouTube, X/Twitter and TikTok.

  • Public proceedings — public mentions of judicial processes, with official confirmation by process number where possible.

  • PEP identification — checks partners against the official Politically Exposed Person registry, distinguishing a confirmed match from a homonym.

  • Relationship graph — companies and people connected by typed, sourced edges (socio_de, relacionada_por_socio), without duplicating entities.

  • Large investigations without blowing the client's context — the result is handed over as a small index plus paginated sections. Nothing is truncated.

Installation

Pick one; all of them run the same Python server over stdio.

Method

Command

Requires

uvx (recommended)

uvx company-investigator-mcp

uv — downloads Python 3.14 automatically if missing

npx

npx -y company-investigator-mcp

Node.js 18+ and uv

pip

pip install company-investigator-mcp, then company-investigator-mcp

Python 3.14+

company-investigator-mcp --version   # prints 1.0.0

The older company-investigator command is kept as an alias.

About the npm package: it is only a launcher, with no server code. It finds uvx and runs uvx company-investigator-mcp@<its own version>, so npm 1.0.0 always runs exactly PyPI 1.0.0 — never @latest. Pin it the usual way (npx -y company-investigator-mcp@1.0.0) to lock a version. If your MCP client cannot find uvx (desktop apps often start with a minimal PATH), the launcher also looks in uv's default install directories; you can set UVX_PATH to the uvx executable explicitly.

Browser (only for buscar_informacoes_publicas)

Installing the package does not download a browser — no large downloads or side effects at install time. The buscar_informacoes_publicas tool uses browser automation (Playwright) and needs Chromium, installed once:

uvx --from company-investigator-mcp playwright install chromium   # uvx / npx users
playwright install chromium                                       # pip (same environment)
uv run playwright install chromium                                # from a git clone

On Linux, add --with-deps if system libraries are missing. Every other tool works without it; if Chromium is missing, this tool returns an error with exactly the commands above. No restart is needed after installing.

From source

git clone https://github.com/CalebePrates/company-investigator-mcp.git
cd company-investigator-mcp
uv sync
uv run company-investigator-mcp

Configuration

No environment variable is required to start the server — ping, buscar_empresa and buscar_informacoes_publicas never depend on them. Without a key, the parts of investigar_empresa that need it (search discovery, official process confirmation, PEP checks) return an empty result with an explanation in limitacoes instead of failing.

Variable

Enables

Where to get it

SEARCH_API_KEY (+ SEARCH_PROVIDER=serper)

News, social profiles, LinkedIn, corporate network discovery, name search

Free tier at serper.dev — 2,500 queries, no card

DATAJUD_API_KEY

Official confirmation of a judicial process by its number (CNJ)

Public shared key published at the DataJud wiki — no personal signup needed

PORTAL_TRANSPARENCIA_API_KEY

Official PEP (Politically Exposed Person) verification

Free email signup at Portal da Transparência

.env.example lists them. The server does not auto-load .env files: pass the variables through your MCP client's env block (below) or export them in the shell that launches the server.

MCP client configuration

Claude Desktop / generic mcpServers JSON

Most clients (Claude Desktop's claude_desktop_config.json, Cursor, Windsurf, …) accept this shape. With uvx:

{
  "mcpServers": {
    "company-investigator": {
      "command": "uvx",
      "args": ["company-investigator-mcp"],
      "env": {
        "SEARCH_PROVIDER": "serper",
        "SEARCH_API_KEY": "your-serper-key",
        "DATAJUD_API_KEY": "the-public-datajud-key",
        "PORTAL_TRANSPARENCIA_API_KEY": "your-cgu-key"
      }
    }
  }
}

With npx, replace the command:

"command": "npx",
"args": ["-y", "company-investigator-mcp"]

With pip, use "command": "company-investigator-mcp" (or its absolute path inside your virtualenv) and no args. All env entries are optional.

If the client reports that uvx was not found, use its absolute path (which uvx / where uvx) as command.

Claude Code

claude mcp add company-investigator \
  -e SEARCH_PROVIDER=serper -e SEARCH_API_KEY=your-serper-key \
  -- uvx company-investigator-mcp

or add the JSON above to .mcp.json at your project root. Reload/reconnect the MCP servers after changing the configuration or the variables.

Windows + WSL

If the server runs inside WSL while the client runs on Windows:

{
  "mcpServers": {
    "company-investigator": {
      "command": "wsl.exe",
      "args": ["-e", "bash", "-lc", "uvx company-investigator-mcp"]
    }
  }
}

bash -lc is a non-interactive login shell: export the API keys in ~/.profile, not ~/.bashrc — Ubuntu's default ~/.bashrc returns early for non-interactive shells, so anything exported there is silently ignored.

Tools

Tool

Purpose

ping

Health check

buscar_empresa(cnpj)

Official registry data for one CNPJ

buscar_informacoes_publicas(url)

Title and visible text of a public web page (needs Chromium)

investigar_empresa(identificador, profundidade=1)

Full investigation; returns an investigation_id and an index

obter_indice_investigacao(investigation_id)

The index again (also for any related company's id)

obter_secao_investigacao(investigation_id, secao, pagina=1, tamanho_pagina=20)

One page (max 50 items) of a section

Resource investigation://{investigation_id}/{secao}{?pagina,tamanho_pagina}

Same as the two tools above, as an MCP Resource (index returns the index)

Every tool self-describes its input schema, so the client discovers them via tools/list. Invalid input (bad CNPJ check digits, malformed URL, unknown section, page out of range, unknown or expired investigation_id) returns a readable tool error.

Examples

ping:

// input
{}
// output
{ "status": "ok", "message": "MCP funcionando" }

buscar_empresa — accepts the CNPJ with or without punctuation:

// input
{ "cnpj": "19.131.243/0001-97" }
// output
{
  "cnpj": "19131243000197",
  "razao_social": "OPEN KNOWLEDGE BRASIL",
  "nome_fantasia": "REDE PELO CONHECIMENTO LIVRE",
  "situacao": "ATIVA"
}

buscar_informacoes_publicas:

// input
{ "url": "https://example.com/" }
// output
{ "url": "https://example.com/", "titulo": "Example Domain", "texto": "Example Domain This domain is for use in ..." }

investigar_empresa — a CNPJ or a company name; profundidade is how many levels of the corporate network to expand (default 1, max 2). An ambiguous name returns candidatos instead of guessing. The answer is a small index (field names exact, values illustrative):

// input
{ "identificador": "19.131.243/0001-97", "profundidade": 1 }
// output
{
  "investigation_id": "3f9c0d…",
  "identificador_usado": "19.131.243/0001-97",
  "empresa": { "cnpj": "...", "razao_social": "...", "situacao": "ATIVA" },
  "processos_status": { "status": "realizada", "motivo": null },
  "secoes": [
    { "nome": "socios", "tipo": "lista", "total_itens": 4 },
    { "nome": "noticias", "tipo": "lista", "total_itens": 45 },
    { "nome": "empresas_relacionadas", "tipo": "lista", "total_itens": 2 }
  ]
}

obter_secao_investigacao — read the content page by page:

// input
{ "investigation_id": "3f9c0d…", "secao": "noticias", "pagina": 1, "tamanho_pagina": 20 }
// output
{
  "secao": "noticias", "pagina": 1, "tamanho_pagina": 20,
  "total_itens": 45, "total_paginas": 3,
  "itens": [
    { "titulo": "...", "url": "https://...", "fonte": "...", "resumo": "...",
      "consultado_em": "...", "data_publicacao": null, "confianca": "media" }
  ]
}

Reading a large investigation

A real investigation with a corporate network can run past 100,000 characters — more than a single tool response should carry. So collection and delivery are separate: the server keeps the complete result in memory and the client pulls it in pages. Paging through every section listed in the index returns 100% of what was collected.

Sections: empresa, candidatos, socios, pessoas_chave, linkedin, redes_sociais, noticias, contatos, processos_confirmados, processos_referencias, processos_status, movimentos_processuais, fontes, empresas_relacionadas, pessoas_relacionadas, relacionamentos, possiveis_relacoes_familiares, peps, limitacoes.

  • Related companies are references, not nested copies. Each item of empresas_relacionadas holds the relationship (origem_socio, fonte, confianca) plus that company's own investigation_id; walk it recursively with the same tools. A company reached through several partners appears once, with one socio_de edge per partner.

  • A process's movements (an old lawsuit can have thousands) live in movimentos_processuais, each item pointing back to its numero_processo; processos_confirmados only carries total_movimentos.

  • Memory only, no database. The store lives in the server process, is capped at 500 records (the least recently used whole investigation tree is discarded first) and disappears when the server restarts. An unknown or expired investigation_id gets a clear error; just run investigar_empresa again.

Sources and evidence

Every item preserves, when available: source (BrasilAPI, Serper, DataJud, Portal da Transparência, LinkedIn via search), URL, discovery date (consultado_em), publication date, confidence (alta / media / baixa — how strong the match is, never a claim of certainty) and, for possible family relationships, the evidence itself (a shared surname token, or the snippet that mentioned a relationship explicitly).

Judicial proceedings separate processos_confirmados (official DataJud data, retrieved by process number) from processos_referencias (a public mention, not confirmed). No official, public, CAPTCHA-free source allows searching processes by party (CNPJ/CPF/name), and DataJud never discloses parties — so confirming a process number is not the same as confirming who is involved in it.

Limitations and responsible use

This project:

  • uses only publicly available information;

  • never accesses private data;

  • never bypasses CAPTCHA, anti-bot mechanisms, authentication, paywalls or rate limits;

  • never treats a matching name as proof of identity;

  • never treats a matching surname as proof of a family relationship — it is only ever a possible relationship, with low confidence unless a public source mentions an explicit kinship term;

  • never interprets appearing in a judicial process as guilt or wrongdoing;

  • treats PEP matches with explicit caution: a name match alone never becomes a confirmed PEP — that requires the visible digits of the partner's masked CPF to match the official record; otherwise the result is a possible homonym;

  • never fabricates a fact when a source cannot verify it — it reports the limitation instead (limitacoes).

Known limitations: search-based discovery depends on what the search provider indexes, so the corporate network and news coverage are not exhaustive; free API tiers have quotas; data is only as current as each public source.

You are responsible for using the results lawfully, including under Brazil's LGPD (Lei Geral de Proteção de Dados) and each source's terms of use. Results are leads to verify, not conclusions.

Architecture

Clean Architecture with an explicit Ports & Adapters boundary:

MCP Client
    ↓
MCP Tools        (interface/mcp_server/tools — validate input, call a use case, shape output)
    ↓
Use Cases        (application/use_cases — orchestrate a single MCP-level operation)
    ↓
Services         (application/services — identification, partner/company/news/social/
                  LinkedIn/process/PEP/family-relationship search, investigation storage)
    ↓
Ports            (domain/ports — small ABCs: one capability each)
    ↓
Adapters         (infrastructure — concrete implementations of a port)
    ↓
External Sources (BrasilAPI, Serper, DataJud, Portal da Transparência, Playwright)

The dependency rule always points inward: domain depends on nothing external (not even Pydantic); application depends only on domain abstractions; infrastructure and interface depend on domain. Every external capability sits behind a small port, so swapping Serper for another search provider means writing one new adapter class. See CLAUDE.md for the full rationale and how each tool's flow works end to end.

src/company_investigator/
├── domain/             # entities, value objects (Cnpj), ports
├── application/        # use cases and services
├── infrastructure/     # BrasilAPI, Playwright, Serper, DataJud, Portal da Transparência,
│                       # in-memory investigation store
└── interface/mcp_server/
    ├── server.py       # composition root
    ├── tools/          # the six MCP tools
    └── resources/      # investigation://{investigation_id}/{secao}
npm/                    # npx launcher (Node, no dependencies, no server logic)

Development

uv sync
uv run pytest                 # test suite (no network, no browser, no paid API)
uv run ruff check .           # lint
uv run ruff format .          # format
(cd npm && npm test)          # npm launcher tests
uv build                      # sdist + wheel in dist/

Every behavior is written test-first. tests/unit covers domain and application logic with fakes for every port; tests/integration exercises the real MCPServer composition, including one test that launches the server as a child process and talks to it over stdio with the official MCP client. CI runs all of this on every push and pull request.

Release process and versioning policy: RELEASING.md. Changes: CHANGELOG.md.

Non-goals

  • Persistence (database, cache, history). The only state is the in-memory investigation store, which lives and dies with the server process.

  • An LLM inside the server. Analysis is the MCP client's / AI agent's job.

License

MIT © Calebe Prates

Available Tools

6 tools
buscar_empresaA

Busca dados cadastrais reais de uma empresa a partir do CNPJ, consultando a BrasilAPI (fonte publica e oficial de dados de CNPJ da Receita Federal). Parametro 'cnpj' (string, obrigatorio): aceita com ou sem pontuacao, por exemplo '12.345.678/0001-90' ou '12345678000190'. Retorna um objeto com 'cnpj' (normalizado, apenas digitos), 'razao_social', 'nome_fantasia' e 'situacao'. Erros possiveis: CNPJ vazio, com letras, com quantidade errada de digitos, com digitos verificadores matematicamente invalidos, falha ao consultar a BrasilAPI, ou CNPJ valido porem sem empresa cadastrada.

Inputs: cnpj (required). Returns: object

buscar_informacoes_publicasA

Abre uma URL publica com um navegador headless e extrai informacoes basicas da pagina: titulo e texto visivel. Nao interage com formularios nem executa acoes na pagina, apenas le o conteudo apos o carregamento. Parametro 'url' (string, obrigatorio): precisa ser uma URL http/https valida e publicamente acessivel. Retorna um objeto com 'url', 'titulo' (pode ser nulo se a pagina nao tiver a tag ou ela estiver vazia) e 'texto' (texto visivel extraido da pagina, sem scripts/estilos). Erros possiveis: URL invalida, timeout ao carregar a pagina, ou falha de navegacao.

Inputs: url (required). Returns: object

investigar_empresaA

Investiga uma empresa a partir de um CNPJ ou de um nome (razao social/nome fantasia), combinando dados cadastrais oficiais (BrasilAPI) com buscas publicas (via uma Search API) por noticias, perfis em redes sociais (LinkedIn, Instagram, Facebook, YouTube, X/Twitter, TikTok), pessoas-chave no LinkedIn, processos judiciais publicos, rede societaria (outras empresas dos socios) e verificacao de PEP. Parametro 'identificador' (string, obrigatorio): um CNPJ (com ou sem pontuacao) ou um nome de empresa. Parametro 'profundidade' (inteiro, padrao 1, maximo 2): quantos niveis de 'socio -> nova empresa' sao expandidos; 0 investiga so a empresa pedida. IMPORTANTE: esta tool NAO devolve os dados completos da investigacao — ela coleta e guarda tudo, e devolve um INDICE pequeno: um 'investigation_id' e, para cada secao (socios, noticias, empresas_relacionadas, processos, peps, etc.), quantos itens existem. Nenhum dado e descartado; para ler o conteudo de uma secao (com todos os seus itens, paginado se for grande), use a tool 'obter_secao_investigacao' com esse investigation_id, ou o resource MCP 'investigation://{investigation_id}/{secao}'. Empresas relacionadas tambem tem sua propria sub-investigacao completa, acessivel pelo investigation_id que aparece dentro da secao 'empresas_relacionadas' — percorra recursivamente para ver 100% da rede.

Inputs: identificador (required), profundidade. Returns: object

obter_indice_investigacaoA

Recupera novamente o indice (resumo estrutural) de uma investigacao ja criada por 'investigar_empresa', usando seu 'investigation_id'. Util para re-consultar quantos itens cada secao tem sem precisar refazer a investigacao. Erro se o investigation_id nao existir.

Inputs: investigation_id (required). Returns: object

obter_secao_investigacaoA

Recupera o conteudo completo (paginado) de UMA secao de uma investigacao criada por 'investigar_empresa', usando o 'investigation_id' que essa tool devolveu. Nenhum dado e descartado: percorrendo todas as paginas de uma secao (veja 'total_paginas' na resposta) voce chega a 100% do que foi coletado. Parametro 'secao' (obrigatorio), uma das: empresa, candidatos, socios, pessoas_chave, linkedin, redes_sociais, noticias, contatos, processos_confirmados, processos_referencias, processos_status, movimentos_processuais, fontes, empresas_relacionadas, pessoas_relacionadas, relacionamentos, possiveis_relacoes_familiares, peps, limitacoes. Para a secao 'empresas_relacionadas', cada item traz seu proprio 'investigation_id' — use-o para percorrer a sub-investigacao completa daquela empresa relacionada (recursivamente, se ela tambem tiver empresas relacionadas). Os movimentos de cada processo confirmado ficam na secao 'movimentos_processuais' (cada item traz o 'numero_processo'), nao dentro de 'processos_confirmados'. Parametros 'pagina' (padrao 1) e 'tamanho_pagina' (padrao 20, maximo 50) controlam a paginacao. Erro se o investigation_id nao existir (ou tiver expirado da memoria do servidor) ou a secao for invalida.

Inputs: secao (required), investigation_id (required), pagina, tamanho_pagina. Returns: object

pingA

Verifica se o servidor MCP esta operante.

Inputs: no named parameters. Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.1/5.0

    Scored across 6 tools

    Disambiguation4/5

    Most tools have clearly distinct purposes, but buscar_empresa (single CNPJ lookup) overlaps with investigar_empresa, which also fetches cadastral data. The obter_indice_investigacao vs obter_secao_investigacao pair is related but the descriptions clearly differentiate index vs section retrieval, so an agent can pick correctly.

    Naming Consistency4/5

    Tools follow a consistent Portuguese verb_noun pattern (buscar_*, obter_*, investigar_*), which is predictable and readable. The lone exception is 'ping', an English outlier, though it is a conventional health-check verb.

    Tool Count5/5

    Six tools is well-scoped for a company-investigation server. Each tool (health check, CNPJ lookup, URL fetch, run investigation, fetch index, fetch section) earns its place without redundancy.

    Completeness4/5

    The investigation lifecycle is well covered: start an investigation, retrieve its index, and page through any section. Minor gaps exist, such as no tool to list previously created investigations or clean them up, but core workflows have no dead ends.

    Maintenance

    ActivitySlowing
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      Enables Brazilian business data lookup through CNPJ (company registry) and CEP (postal code) queries, with intelligent web search capabilities powered by Tavily for due diligence, compliance, and customer verification.
      92 npm
      10
      MIT
    • A
      license
      Not graded
      quality
      B
      maintenance
      Brazilian company-registry lookup via Receita Federal, allowing AI agents to query CNPJ data.
      306 npm
      MIT
    • F
      license
      A
      quality
      C
      maintenance
      Enables AI assistants to perform OSINT investigations, web searches, deep website scraping, contact extraction, and Brazilian company data enrichment via CNPJ, including 360-degree company and person lookups.
      6
      -