100% local-first

CodeSteer Atlas

Servidor MCP local para busca semântica híbrida, indexação incremental e grafo de conectividade em código e documentos

01

O que é o Model Context Protocol (MCP)?

O Model Context Protocol (MCP) é um protocolo aberto de comunicação bidirecional criado para padronizar a forma como Modelos de Linguagem (LLMs), rodando em clientes como editores de código (Cursor, VS Code, Claude Desktop, Cline), interagem de forma segura com fontes de dados e ferramentas locais ou remotas.

Em vez de cada LLM ou IDE escrever integrações proprietárias para ler arquivos, pesquisar em bancos de dados ou executar comandos, eles atuam como Clientes MCP genéricos que se conectam a um ou mais Servidores MCP por canais estruturados.

Detalhe técnico crucial: O transporte oficial do CodeSteer Atlas utiliza stdio (Standard Input/Output) e mensagens serializadas em JSON-RPC 2.0, não requisições HTTP tradicionais. Isso elimina overhead de conexões de rede e simplifica o ciclo de vida do processo local.
02

Como o protocolo funciona na prática?

O ciclo de vida de uma conexão MCP local é simples, robusto e estruturado em 3 fases principais controladas pelo host (a IDE):

1

Inicialização (Handshake)

O cliente inicia o processo do servidor e troca informações de capacidades (versão do protocolo, ferramentas e recursos disponíveis).

2

Descoberta (Listing)

O cliente pergunta ao servidor: "Quais ferramentas você expõe?". O Atlas responde com a assinatura e descrição de suas 5 ferramentas (ex: atlas_search, atlas_graph).

3

Execução (Tool Call)

Quando a IA precisa de informações do repositório, envia um JSON-RPC chamando uma tool. O Atlas processa, consulta o LanceDB localmente e retorna o JSON estruturado.

Conceitos Primitivos do MCP

  • Tools (Ações): Funções executáveis com argumentos declarados que a IA pode invocar. Possuem schemas definidos via Pydantic para validação automática de entrada.
  • Resources (Dados passivos): URIs que servem como arquivos ou streams somente-leitura de dados (ex: o Atlas expõe o resource atlas://status contendo metadados de diagnóstico).
  • Prompts (Templates): Modelos de prompts pré-configurados que ajudam o usuário a estruturar fluxos complexos de chat.
Exemplo de Mensagem JSON-RPC 2.0 — Tool Call para atlas_search
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "atlas_search",
    "arguments": {
      "query": "sistema de autenticação JWT",
      "top_k": 3
    }
  },
  "id": 42
}
Isolamento da Stream de Stdout: Como o protocolo JSON-RPC usa a saída padrão (stdout) para as respostas, o Atlas redireciona imediatamente todo o sys.stdout para o sys.stderr no momento do import das bibliotecas. Apenas no momento final de inicialização do FastMCP a stream limpa do stdout é restaurada. Logs de debug ou saídas nativas de C/Rust (onnxruntime, tantivy) vão para stderr, impedindo a corrupção do JSON-RPC!
03

O Pipeline de Indexação do Atlas

Para responder a buscas semânticas instantâneas sem gastar tokens, o CodeSteer Atlas constrói um índice vetorial, textual e um grafo de conectividade na pasta local .code-index. O processo é orquestrado por index_workspace() em indexer.py e segue 6 fases ponderadas:

1

Scan

Varredura recursiva do workspace (ou subpastas em --paths). Ignora node_modules, .git, .atlasignore e arquivos > 2 MB.

2

Hash

Compara mtime + size e sha256 com manifest.json. Fast path evita reler arquivos inalterados.

3

Chunk

Parse AST (Tree-sitter) ou estratégias textuais. Extrai símbolos, imports e rationale refs (DECISAO-XXX).

4

Embed

Vetores 384d com all-MiniLM-L6-v2 via fastembed — apenas chunks novos ou alterados.

5

Persist

Grava no LanceDB, atualiza FTS (BM25) e o manifest.json (incremental ou rebuild com --full).

6

Graph

Atualiza graph.json/graph.html com a estratégia mais barata possível: pula se nada mudou, faz rebuild incremental quando só código já indexado foi alterado, ou reconstrói tudo nos demais casos.

Indexação Incremental

A indexação padrão é 100% incremental baseada em arquivos. Ela compara o hash SHA-256 atual de cada arquivo com o mapa persistido em manifest.json.

  • Novo arquivo: Chunking → Embeddings → Salva no banco.
  • Arquivo alterado: Remove chunks antigos associados ao caminho no LanceDB → Gera novos chunks → Salva.
  • Arquivo deletado: Apenas remove os chunks antigos correspondentes no LanceDB.
  • Forçar Reconstrução: O parâmetro --full reconstrói completamente a tabela, sobrescrevendo todo o banco.
Composição dos Componentes Internos
CLI: atlas-index MCP: atlas_index indexer.py / index_workspace() ASTChunker EmbeddingEngine StorageBackend

O que fica em .code-index/

manifest.json

Hashes sha256, metadados, git HEAD, versão do índice. Usado por atlas_status e indexação incremental.

lancedb/

Tabela chunks com vetores + texto. Alimenta atlas_search (híbrido) e atlas_map.

graph.json

Grafo derivado: arquivos, símbolos, docs, imports e cites. Consultado por atlas_graph.

graph.html

Viewer offline com busca, filtros e pan/zoom. Abra via file:// — caminho em graph_viewer_path.

Workspace com várias pastas ou repos

Você pode indexar subpastas específicas com --paths repetido ou via MCP paths=["frontend", "backend"]. Para workspaces com múltiplos repositórios git aninhados, a abordagem recomendada é um único .code-index na pasta pai.

✓ Suportado

  • Indexar várias subpastas: -p frontend -p backend
  • Filtrar busca: path_prefix="backend/"
  • Indexação incremental por subárvore
  • Pastas .git ignoradas automaticamente

⚠ Limitações atuais

  • MCP usa um índice por processo — não mergeia dois .code-index
  • Campo repo nos chunks = nome da pasta workspace, não cada repo filho
  • is_stale só reflete git na raiz do workspace
Indexar múltiplas pastas no mesmo workspace
uv run atlas-index --workspace . --paths src --paths docs --paths cognitive-base

# Via MCP (síncrono quando paths está definido)
atlas_index(paths=["src", "docs"])

Onde fica o .code-index?

O servidor MCP precisa localizar a pasta .code-index do projeto antes de buscar ou indexar. A resolução segue uma cadeia de prioridade fixa (DECISAO-002). O campo index_resolution retornado por atlas_status indica qual mecanismo foi usado — útil para diagnosticar plugins globais iniciados com CWD diferente da raiz do projeto (ex.: HOME).

  1. --index-dir — argumento de linha de comando do servidor (index_resolution: "cli-arg").
  2. ATLAS_INDEX_DIR — variável de ambiente explícita ("env").
  3. Discovery ascendente a partir do CWD — sobe diretórios procurando uma pasta .code-index existente, estilo .git ("discovery").
  4. Raiz informada pelo editorCLAUDE_PROJECT_DIR (Claude Code) ou WORKSPACE_FOLDER_PATHS (Cursor/VS Code), quando o CWD do plugin não é a raiz do projeto ("editor-project-dir" ou "editor-project-dir-fallback").
  5. MCP roots (upgrade na 1ª tool call) — se a resolução de startup caiu em fallback, a primeira chamada a uma tool consulta roots/list do cliente MCP, localiza ou aponta o índice para a raiz real do workspace ("roots" ou "roots-fallback"). Cobre plugins globais (Copilot, Cursor, Kiro) sem configuração por projeto.
  6. Fallback final.code-index relativo ao CWD ou à raiz do editor ("cwd-fallback").
Plugins globais: quando o servidor é registrado como plugin (não por projeto), ele costuma iniciar com CWD = HOME. Sem os passos 4 e 5, o Atlas apontaria para um índice errado. Use atlas_status e verifique index_resolution e index_path se a busca retornar índice inexistente ou vazio.

Reindex automático em background

Ao iniciar o servidor MCP (atlas-serve), se já existir um índice local, o Atlas dispara uma reindexação incremental em subprocesso — sem bloquear o canal stdio JSON-RPC. Operações pesadas (LanceDB, Tantivy FTS, ONNX) rodam fora do processo do servidor para não congelar chamadas MCP.

  • Lock de reindex: apenas um processo reindexa por vez; atlas_status expõe reindexing: true enquanto o lock estiver ativo.
  • Log: saída em .code-index/background_reindex.log, com cabeçalhos timestamped por execução.
  • atlas_index assíncrono: indexação do workspace inteiro ou com full=true também roda em background e retorna imediatamente com status, pid e log_path. Indexação de subpastas específicas (paths não vazio, full=false) permanece síncrona.
04

Indexação de Código com parsing AST

Diferente de sistemas ingênuos de busca que quebram o código baseados em números de linhas fixas (o que pode cortar uma função ao meio e quebrar sua coerência lógica), o CodeSteer Atlas utiliza um analisador sintático completo: o Tree-sitter.

O analisador lê o código-fonte de linguagens como Python, JavaScript, TypeScript, Go, Java, C#, C++, Rust, Kotlin, etc., e monta uma Árvore Sintática Abstrata (AST).

Características da indexação AST

  • Granularidade Semântica: O gerador de chunks (ASTChunker) extrai apenas nós relevantes de escopo como classes (class), funções (function) e métodos (method).
  • Nomes Hierárquicos: Chunks aninhados recebem nomenclatura estruturada refletindo o escopo, facilitando a identificação (ex: um método dentro de uma classe vira ClasseExemplo.nome_do_metodo).
  • Fallback Seguro: Se o arquivo não contiver símbolos identificáveis (scripts sequenciais, arquivos de configuração), o módulo cria um único chunk do tipo module contendo todo o arquivo.
  • Truncamento Inteligente: Quando um chunk excede o limite estimado do modelo (~1000 caracteres), o Atlas preserva as 7 primeiras linhas (contendo assinatura e docstring) e as 3 últimas linhas (retorno), inserindo uma marcação de truncamento no meio. Isso economiza contexto e mantém a assinatura visível para a IA.
Estrutura de Chunks AST de um Arquivo Python
Arquivo auth_service.py
Classe AuthService (Linhas 5-42)
Método AuthService.__init__ (Linhas 6-8)
Método AuthService.login (Linhas 10-25)
Método AuthService.logout (Linhas 27-42) [Truncado]
Função hash_password (Linhas 45-50)
05

Indexação de Texto e Documentos

Arquivos de documentação (como Markdown ou arquivos de texto puro) ou scripts sem estrutura orientada a objetos (como arquivos SQL ou JSON) não possuem uma hierarquia clássica de classes e métodos. Por isso, o ASTChunker adota estratégias específicas e otimizadas para cada tipo de formato:

Estratégias de Chunking por Formato

Tipo de Arquivo Estratégia Principal Tipo de Escopo Comportamento em Blocos Grandes (>1000 caracteres)
Código AST
.py, .js, .go, .java, .cs...
Nós da árvore sintática (Classes, Funções, Métodos) via Tree-sitter class, method, function Truncamento inteligente: preserva 7 linhas iniciais + 3 finais, cortando o meio.
Markdown
.md
Divisão estrutural baseada em cabeçalhos (#, ##, ###) section Quebra recursiva em múltiplos sub-chunks divididos por parágrafos (\n\n).
SQL
.sql
Identificação de declarações (Statements) via parser Tree-sitter SQL table, view, query... Statements imensos são cortados em múltiplos blocos respeitando as quebras de linha.
Texto / Outros
.txt, .xml, .json, .yaml...
Quebra baseada em parágrafos ou linhas estruturadas chunk Agrupamento sequencial de parágrafos acumulando até o limite de 1000 caracteres.

Amostra de Extensões Suportadas (SUPPORTED_EXTENSIONS)

python (.py) javascript (.js, .jsx) typescript (.ts, .tsx) go (.go) rust (.rs) csharp (.cs) java (.java) c/c++ (.c, .cpp, .h) sql (.sql) markdown (.md) text (.txt) yaml (.yaml, .yml) json (.json) toml (.toml) html/css (.html, .css) xml (.xml) dart (.dart) pascal (.pas) vb6 (.bas, .cls, .frm) razor (.cshtml, .razor)

Referências cruzadas em Markdown (busca enriquecida)

Além de indexar seções Markdown por cabeçalhos, o atlas_search enriquece resultados language=="markdown" com o campo opcional markdown_references — sem reindexar nem alterar o schema LanceDB. O enriquecimento é feito em tempo de busca a partir do conteúdo do chunk.

  • Links padrão: [texto](destino.md) e [texto](destino.md#secao)
  • Wikilinks Obsidian: [[destino]], [[destino|alias]], [[destino#Secao]], ![[embed]]
  • Resolução de wikilinks "bare": nomes sem path (ex.: [[mcp-server]]) são resolvidos globalmente contra o mapa de arquivos .md do manifest.json; ambiguidade retorna lista de candidates.
  • Âncoras: quando o destino está indexado, o campo resolved_section pode mapear #secao ao nome da seção correspondente.
Trecho de resposta atlas_search — markdown_references
{
  "file_path": "docs/architecture.md",
  "language": "markdown",
  "symbol": "Pipeline de Indexação",
  "score": 0.041,
  "markdown_references": [
    {
      "file_path": "docs/mcp-overview.md",
      "anchor": "stdio-transport",
      "resolved_section": "Transporte stdio"
    },
    {
      "file_path": "docs/obsidian-vault/note.md",
      "anchor": null,
      "resolved_section": null
    }
  ]
}

Rationale refs em código (grafo + busca)

Comentários estruturados no código viram metadados persistidos no índice e arestas no grafo. Resultados de atlas_search podem incluir rationale_refs apontando para notas de decisão.

  • Cites: DECISAO-005, DEC-002, ADR-001, RFC-012
  • Anotações: # WHY:, # NOTE: (ou //, --)
  • Wikilinks em comentários: resolvidos contra arquivos .md do manifest
Exemplo — comentário que alimenta o grafo
# DECISAO-005: embeddings locais com fastembed
# WHY: manter indexação 100% offline — nenhum código sai da máquina
def encode(self, texts: list[str]) -> list[list[float]]:
    ...
06

Grafo de Conhecimento Derivado

Além da busca semântica, o Atlas deriva um grafo de conectividade a cada indexação. Ele mapeia relações explícitas entre código, documentação, imports e rationale — não substitui atlas_search, mas responde perguntas do tipo "como A se conecta a B?".

atlas_search

Localizar por conceito ou símbolo — busca híbrida vetorial + BM25.

atlas_graph

Explorar hubs, caminhos e vizinhança — conectividade e rationale.

graph.html

Exploração visual offline — pan, zoom, filtros e foco local.

Tipos de nó e aresta

Nós (kind) Exemplo Arestas (kind) Significado
file, doc src/server.py, dec-002.md contains Arquivo contém símbolo ou seção
symbol index_workspace imports Import Python ou JS/TS relativo
section Heading markdown links_to Link ou wikilink entre docs
rationale Texto de WHY: / NOTE: cites Referência DECISAO-XXX no código
annotates Comentário rationale ligado ao símbolo

Tool atlas_graph — três modos

Lê o graph.json já gerado — não reconstrói o grafo. Reindexe com atlas_index se o grafo estiver ausente (índices < 2.1.0).

hubs

Nós centrais

Retorna os nós mais conectados (maior grau). Ideal para descobrir documentos e código “hub” do projeto.

atlas_graph(mode="hubs", top_n=10)
explain

Vizinhança

Resume arquivos, docs citados e rationale ligados a um símbolo, arquivo ou nota.

atlas_graph(mode="explain",
  target="index_workspace")
path

Caminho BFS

Encontra rota entre dois nós (até 10 saltos). Aceita id, label ou sufixo único.

atlas_graph(mode="path",
  source="index_workspace",
  target="dec-002")

Visualizador graph.html

Após indexar, abra o HTML autocontido em .code-index/graph.html. O caminho absoluto aparece em atlas_statusgraph_viewer_path.

  • Busca por label ou id de nó
  • Clique em nó para focar subgrafo local
  • Filtros por tipo de nó e aresta
  • Grafos grandes (> 3000 nós): modo hubs-only com opção “Expandir tudo”
  • Debug: adicione ?debug=1 na URL
Upgrade de índice: se atlas_graph retornar erro de graph.json ausente, rode uv run atlas-index --workspace . --full para regenerar grafo e viewer (requer índice versão 2.1.0+).
07

Busca Híbrida e Embeddings Locais

Para obter a máxima precisão nas respostas sem perder a velocidade e o contexto sintático, o CodeSteer Atlas utiliza um motor de Busca Híbrida de dois braços paralelos. A busca combina o melhor de duas abordagens:

1. Braço Semântico (Vetor)

Conceito: Busca por similaridade de cosseno nos embeddings gerados.

Modelo: all-MiniLM-L6-v2 local via biblioteca fastembed (ONNX Runtime, 384 dimensões).

Vantagem: Encontra conceitos equivalentes mesmo sem palavras-chave idênticas (ex: busca por "inicializar banco" encontra o método Database.connect()).

2. Braço Léxico (Full-Text Search)

Conceito: Busca de texto completo baseada no algoritmo tradicional BM25 (via Tantivy integrado ao LanceDB).

Mecanismo: Índice invertido clássico construído na coluna de conteúdo dos chunks.

Vantagem: Encontra termos específicos, siglas de métodos ou strings exatas (ex: buscar por um código de erro específico como ERR_AUTH_FAILED).

Fusão de Rankings: Reciprocal Rank Fusion (RRF)

Após coletar de forma independente as listas de melhores candidatos de cada braço (configurado pela constante CANDIDATES_LIMIT = 50), o Atlas funde os resultados em um único ranking unificado usando o algoritmo matemático RRF (Reciprocal Rank Fusion):

Score RRF = ∑ m ∈ M &frac;1;{rankm(c) + k}

Onde c é o chunk de código, M representa os sistemas de busca (Vetorial e FTS), rankm(c) é a posição do chunk no ranking daquele sistema (1-indexed), e k é a constante de suavização configurada como 60 (RRF_K = 60).

Dessa forma, arquivos que aparecem bem posicionados em ambos os motores ganham prioridade absoluta, garantindo um resultado final superior a qualquer um dos métodos isolados.

08

As 5 Ferramentas (Tools) do Atlas

O servidor MCP expõe cinco ações principais. Use atlas_search para localizar código, atlas_graph para conectividade, e atlas_status apenas para diagnóstico explícito.

atlas_search Busca Híbrida

Busca semântica híbrida (vetorial + BM25) no índice local. Retorna metadados por padrão; use include_content=true ou Read nas linhas indicadas. Resultados de código podem incluir rationale_refs; Markdown inclui markdown_references.

Argumentos: query, top_k, path_prefix, language, include_content
atlas_map Arquitetura

Mapa hierárquico de classes, funções, métodos e seções Markdown. Panorama estrutural token-eficiente.

Argumentos: path_prefix, max_depth, repo
atlas_graph Conectividade

Consulta o grafo derivado (graph.json): hubs centrais, caminhos BFS entre nós e vizinhança com docs/rationale. Use quando a pergunta for sobre relações, não localização.

Modos: hubs, explain, path — ver seção Grafo
atlas_status Diagnóstico

Metadados do índice: is_stale, reindexing, index_resolution, graph_available, graph_viewer_path. Não é pré-requisito para busca.

Campos-chave: total_chunks, index_path, git_head_sha
atlas_index Indexador

Indexa ou reindexa o workspace. dry_run=true lista candidatos e, em workspaces grandes (> 200 arquivos elegíveis), recomenda paths específicos em vez de indexação completa. Workspace inteiro ou full=true rodam em background; paths específicos são síncronos. Atualiza graph.json/graph.html conforme a estratégia mais barata (ver fase Graph acima).

Argumentos: workspace, paths, full, dry_run
Retorno inclui: phase_durations_s (tempo por fase), graph_strategy (full/incremental-code/skipped-unchanged), files_scanned, files_eligible, chunks_generated, graph_nodes, graph_edges, graph_bytes, graph_html_bytes
09

Princípio Constitucional: 100% Local-First

Soberania e Privacidade de Código

Em conformidade absoluta com o artigo I da constituição do CodeSteer Atlas (.memory-bank/constitution.md), todo o processamento de código-fonte e documentação é realizado de forma local e offline na máquina do usuário.

Nenhum fragmento de código, nome de classe ou comentário é enviado para APIs de terceiros para fins de vetorização ou persistência. O modelo de embeddings (all-MiniLM-L6-v2) é executado localmente via runtime ONNX na CPU da máquina, e o banco de dados LanceDB opera de forma embutida, salvando arquivos puramente locais na pasta .code-index/.

Início rápido (sem clonar o repositório)

Para usar o Atlas em qualquer projeto, basta registrar o servidor MCP no seu cliente e indexar o workspace uma vez. O pacote roda via uvx, direto do GitHub — 100% local após o download inicial das dependências.

1. Indexar o projeto

uvx --from git+https://github.com/LuisCarlosLopes/codesteer-atlas.git \
  atlas-index --workspace .

2. Registrar no cliente MCP

Copie o manifest do seu editor (.cursor/mcp.json, .vscode/mcp.json, etc.) ou instale como plugin:

  • Claude Code: /plugin install codesteer-atlas
  • Copilot CLI: copilot plugin install LuisCarlosLopes/codesteer-atlas
  • Kiro: importar Power do GitHub

Pronto para integrar ao seu fluxo de trabalho?

Explore o guia completo de instalação, variáveis de ambiente e configuração manual em outros clientes.