MCPunk
Explore e entenda bases de código por meio de conversas, dividindo arquivos em partes lógicas para busca e consulta sem embeddings.
Documentação
MCPunk 🤖
Converse com seu código sem embeddings, dando ao LLM ferramentas para buscar seu código de forma inteligente.
O MCPunk permite que você explore e entenda bases de código por meio de conversa. Ele funciona assim:
- Divide arquivos em blocos lógicos (funções, classes, seções de markdown)
- Dá ao LLM ferramentas para buscar e consultar esses blocos
- Deixa o LLM encontrar o código específico que precisa para responder suas perguntas
Sem embeddings, sem configuração complexa — apenas buscas claras e auditáveis que você pode ver e orientar. Funciona muito bem com Claude Desktop ou qualquer outro cliente MCP.
Construído com os seguintes princípios em mente
- Contexto é Rei - LLMs podem ser ótimos, mas apenas se receberem contexto adequado.
- Contexto é Precioso - LLMs precisam de contexto, mas não conseguem lidar com muito. Uma tragédia! MCPunk é RAG que inerentemente fornece ao LLM dicas contextuais, permitindo que o LLM foque apenas no conteúdo relevante.
- Humano no Ciclo - Você pode ver exatamente quais dados o LLM considerou e como os encontrou, Você pode entrar no chat e direcionar as coisas como quiser.
Configuração
Estas são instruções para Claude Desktop, mas o MCPunk pode ser usado em qualquer lugar onde MCP seja usado.
- Instale o uv
- Coloque o trecho abaixo no seu
claude_desktop_config.json(Detalhes sobreclaude_desktop_config.jsonincluindo localização) - Reinicie o Claude Desktop e você deverá ver as ferramentas disponíveis após um pequeno atraso, como na captura de tela abaixo
- Converse à vontade: "ei cara, você pode configurar o projeto ~/git/mcpunk e me dizer como arquivos python são divididos em blocos?"
("command": "uvx", pode não funcionar, e você pode precisar usar, por exemplo, "command": "/Users/michael/.local/bin/uvx",)
{
"mcpServers": {
"MCPunk": {
"command": "uvx",
"args": ["mcpunk"]
}
}
}

Exemplos de Uso
Responder Perguntas Sobre Sua Base de Código
- [Usuário] Ei cara, você pode configurar o repositório ~/git/mcpunk e depois me ajudar a entender como um usuário do mcpunk obteria o diff git da branch atualmente checkout no repositório que ele configurou com o mcpunk
- [Claude] Chama
configure_project - [Claude] Chama
list_all_files_in_project - [Claude] Chama
find_files_by_chunk_content - [Claude] ... faz um total de 21 chamadas de ferramentas com o MCPunk.
- [Claude] Agora entendo como a funcionalidade de diff git funciona no mcpunk.
Deixe-me resumir como um usuário obteria o diff git da branch atualmente checkout:
Para obter um diff git da branch atualmente checkout em um repositório configurado com mcpunk:
- Primeiro, o usuário precisa configurar o mcpunk para trabalhar com seu projeto usando a ferramenta configure_project
- Para ver quais branches foram recentemente checkout (para identificar contra o que fazer diff)
- Depois, para obter o diff entre a branch atual (HEAD) e uma branch de referência Isso exibirá as diferenças entre a branch atual (HEAD) e a branch de referência especificada. O parâmetro ref deve ser o nome da branch base (como "main" ou "develop") que você deseja comparar.
- [Usuário] Ótimo trabalho, cara!
Revisão de PR
- [usuário] Ei cara, você pode configurar o repositório ~/git/mcpunk e dar uma
olhada na branch atual versus
scratch/1.5 - [Claude] Configura ~/git/mcpunk e chama
diff_with_refpara refscratch/1.5 - [Claude] Vejo que você fez várias alterações, principalmente adicionando um novo arquivo
de teste
tests/test_git_analysis.py... - [usuário] como isso se encaixa no resto da base de código?
- [Claude] Faz 5 chamadas de ferramentas para listar arquivos por blocos, listar blocos, buscar detalhes de blocos
- [Claude] Entendo - o código analisa a saída do git reflog para rastrear branches recentemente checkout. A função principal get_recent_branches recebe um caminho de repositório e retorna as últimas N branches que foram checkout, usando _branches_from_reflog como auxiliar para analisar a saída bruta do reflog.
- [Usuário] Se você estivesse com pressa e tivesse que direcionar alguém para revisar este trabalho, o que você direcionaria para olhar? Por favor, descreva peças discretas de trabalho
- [Claude]
- O
split("to ")[-1]em _branches_from_reflog parece frágil - Os dados de teste mostram apenas nomes de branch simples, e espaços/caracteres especiais?
- O example_reflog é representativo da saída real do git reflog?
- Estamos testando contra o comportamento real do git?
- O
- [Usuário] Você é o melhor!
Trabalhar em Múltiplas Bases de Código
Você pode simplesmente pedir ao seu LLM para configurar vários projetos, e ele pode consultar livremente entre eles. Útil se um depende do outro e estiverem em repositórios diferentes. Nesse caso, o LLM deve reconhecer isso por meio de imports.
O que é MCPunk e Outros Contextos
MCPunk é um servidor MCP que fornece ferramentas para
- Configurar um projeto, que é um diretório de arquivos. Quando configurado, os arquivos serão divididos em blocos lógicos. MCPunk é construído para código, mas na verdade poderia ser aplicado a qualquer documento, até mesmo imagens, se você quiser.
- Buscar arquivos em um projeto que contenham texto específico
- Buscar blocos em um arquivo que contenham texto específico
- Visualizar o conteúdo completo de um bloco específico
Além disso, ele fornece alguns divisores de blocos integrados. O mais maduro é o divisor de Python.
MCPunk não precisa ser usado apenas para conversa. Ele pode ser usado como parte de revisão de código em um pipeline de CI, por exemplo. É realmente RAG geral.
sequenceDiagram
participant User
participant Claude as Claude Desktop
participant MCPunk as MCPunk Server
participant Files as File System
Note over User,Files: Setup Phase
User->>Claude: Ask question about codebase
Claude->>MCPunk: configure_project(root_path, project_name)
MCPunk->>Files: Scan files in root directory
Note over MCPunk,Files: Chunking Process
MCPunk->>MCPunk: For each file, apply appropriate chunker:
MCPunk->>MCPunk: - PythonChunker: functions, classes, imports
MCPunk->>MCPunk: - MarkdownChunker: sections by headings
MCPunk->>MCPunk: - VueChunker: template/script/style sections
MCPunk->>MCPunk: - WholeFileChunker: fallback
MCPunk->>MCPunk: Split chunks >10K chars into parts
MCPunk-->>Claude: Project configured with N files
Note over User,Files: Navigation Phase<br>(LLM freely uses all these tools repeatedly to drill in)
Claude->>MCPunk: list_all_files_in_project(project_name)
MCPunk-->>Claude: File tree structure
Claude->>MCPunk: find_files_by_chunk_content(project_name, "search term")
MCPunk-->>Claude: Files containing matching chunks
Claude->>MCPunk: find_matching_chunks_in_file(project_name, file_path, "search term")
MCPunk-->>Claude: List of matching chunk IDs in file
Claude->>MCPunk: chunk_details(chunk_id)
MCPunk-->>Claude: Full content of specific chunk
Claude->>User: Answer based on relevant code chunks
Note over User,Files: Optional Git Analysis
Claude->>MCPunk: list_most_recently_checked_out_branches(project_name)
MCPunk->>Files: Parse git reflog
MCPunk-->>Claude: List of recent branches
Claude->>MCPunk: diff_with_ref(project_name, "main")
MCPunk->>Files: Generate git diff
MCPunk-->>Claude: Diff between HEAD and reference
Curso Intensivo de RAG Itinerante
Veja
- https://arcturus-labs.com/blog/2024/11/21/roaming-rag--make-_the-model_-find-the-answers/
- https://simonwillison.net/2024/Dec/6/roaming-rag/
A essência do RAG itinerante é
- Dividir o conteúdo (uma base de código, arquivos PDF, o que for) em "blocos". Cada bloco é um item lógico "pequeno", como uma função, uma seção em um documento markdown ou todos os imports em um arquivo de código.
- Fornecer ao LLM ferramentas para buscar blocos. MCPunk faz isso fornecendo ferramentas para buscar arquivos que contenham blocos com texto específico e para listar o conteúdo completo de um bloco específico.
Comparado ao RAG mais tradicional de "busca vetorial":
- O LLM precisa aprofundar para encontrar blocos e naturalmente está ciente do contexto mais amplo (como em qual arquivo estão)
- Os blocos devem ser sempre coerentes. Como uma função completa.
- Você pode ver exatamente o que o LLM está buscando, e geralmente é óbvio se ele está buscando mal e você pode ajudá-lo sugerindo termos de busca melhorados.
- Requer correspondência exata na busca. MCPunk NÃO fornece busca difusa de nenhum tipo.
Blocos
Um bloco é uma subseção de um arquivo. Por exemplo,
- Uma única função Python
- Uma seção de markdown
- Todos os imports de um arquivo Python
Os blocos são criados a partir de um arquivo por divisores de blocos, e o MCPunk vem com vários integrados.
Quando um projeto é configurado no MCPunk, ele percorre todos os arquivos e aplica o primeiro divisor de blocos aplicável a cada um. O LLM pode então usar ferramentas para (1) consultar arquivos que contenham blocos com texto específico, (2) consultar todos os blocos em um arquivo específico e (3) buscar o conteúdo completo de um bloco.
Essa base fundamental permite que o Claude navegue efetivamente por bases de código relativamente grandes, começando com uma busca ampla por arquivos relevantes e estreitando para áreas relevantes.
Divisores de blocos integrados:
PythonChunkerdivide coisas em classes, funções, imports de nível de arquivo e declarações de nível de arquivo (ex.: globais). Aplicável a arquivos que terminam em.pyVueChunkerdivide em blocos 'template', 'script', 'style' - ou quaisquer itens de<blah>....</blah>de nível superior que existam. Aplicável a arquivos que terminam em.vueMarkdownChunkerdivide coisas em seções de markdown (por título). Aplicável a arquivos que terminam em.mdWholeFileChunkerdivisor de blocos de fallback que cria um único bloco para o arquivo inteiro. Aplicável a qualquer arquivo.
Qualquer bloco com mais de 10 mil caracteres (configurável) é automaticamente dividido em
vários blocos, com nomes sufixados com part1, part2, etc. Isso ajuda
a evitar estourar o contexto, enquanto ainda permite navegação razoável pelos blocos.
Divisores de Blocos Personalizados
Cada tipo de arquivo (ex.: Python vs C) precisa de um divisor de blocos personalizado. O MCPunk vem com alguns integrados. Se nenhum divisor de blocos específico corresponder a um arquivo, um divisor padrão que simplesmente coloca o arquivo inteiro em um bloco é usado.
A forma atual sugerida de adicionar blocos é fazer um fork deste projeto e adicioná-los, e executar o MCPunk conforme Desenvolvimento. Para adicionar um divisor de blocos
- Adicione-o em file_chunkers.py, herdando de
BaseChunker - Adicione-o a
ALL_CHUNKERSem file_breakdown.py
Seria possível implementar algum tipo de sistema de plugins para módulos anunciarem que têm divisores de blocos personalizados para o MCPunk usar, como o sistema de plugins do pytest, mas atualmente não há planos para implementar isso (a menos que alguém queira fazer).
Limitações
- Às vezes o LLM é ruim em buscar. Ex.: buscar por "dependency", perdendo termos como "dependencies". Há espaço para aplicar stemming.
- Às vezes o LLM tentará encontrar uma peça específica de código crítico, mas falhará em encontrá-la e continuará sem reconhecer que tem consciência contextual limitada.
- Projetos "grandes" não são bem testados. Um projeto com ~1000 arquivos Python contendo no total ~250k linhas de código funciona bem. Leva ~5s para configurar o projeto. Conforme o tamanho da base de código aumenta, o tempo para realizar a divisão inicial em blocos aumentará, e provavelmente será necessária uma busca mais sofisticada. O código geralmente não é escrito pensando em bases de código massivas - você verá coisas como todos os dados armazenados em memória, busca feita iterando sobre todos os dados, várias coisas que estão pedindo por otimização básica.
- Projetos pequenos provavelmente são melhores com todo o código concatenado e jogado no contexto. MCPunk só é realmente apropriado onde isso é impraticável.
- Em alguns casos, seria obviamente melhor permitir que o LLM pegasse um arquivo inteiro em vez de escolher blocos um a um. MCPunk não tem mecanismo para isso. Na prática, não achei isso um grande problema.
Configuração
Várias coisas podem ser configuradas por meio de variáveis de ambiente prefixadas com MCPUNK_.
Para opções disponíveis, veja settings.py - elas são carregadas
de variáveis de ambiente via Pydantic Settings.
Por exemplo, para configurar a opção include_chars_in_response:
{
"mcpServers": {
"MCPunk": {
"command": "uvx",
"args": ["mcpunk"],
"env": {
"MCPUNK_INCLUDE_CHARS_IN_RESPONSE": "false"
}
}
}
}
Roadmap e Estado do Desenvolvimento
MCPunk é considerado quase completo em funcionalidades. Ele não teve uso amplo, e como usuário é provável que você encontre bugs ou arestas. Relatos de bugs são bem-vindos em https://github.com/jurasofish/mcpunk/issues
Ideias de Roadmap
- Adicionar um monte de prompts para ajudar no uso do MCPunk. Sem prompts reais do tipo "explique como fazer uma panqueca para um alienígena", as coisas caem um pouco no vazio.
- Incluir comentários de nível de módulo ao extrair declarações de nível de módulo em Python.
- Possivelmente stemming para busca
- Mudar todo o conceito de "projeto" para não precisar que os arquivos existam de fato - isso
levaria a permitir arquivos "virtuais" dentro do projeto.
- Considerar mudar arquivos de terem um caminho para terem uma URI, então poderia ser como
file://.../http[s]:///gitdiff:/// etc URIs arbitrárias
- Considerar mudar arquivos de terem um caminho para terem uma URI, então poderia ser como
- Divisão em blocos de diffs git. Atualmente, há uma ferramenta para buscar um diff inteiro. Isso
pode ser muito grande. Em vez disso, a ferramenta poderia ser alterada para
add_diff_to_projecte colocar arquivos sob a URIgitdiff://ou sob algum caminho falso - Cache de um projeto, para não precisar reanalisar todos os arquivos toda vez que você reiniciar o cliente MCP. Isso pode ser complicado, pois mudanças no código de um divisor de blocos invalidarão o cache. Provavelmente não será priorizado, já que não é tão lento para meus casos de uso.
- Capacidade de os usuários fornecerem código personalizado para realizar a divisão em blocos, talvez semelhante a plugins do pytest
- Algo como tree sitter poderia possivelmente ser usado para um divisor de blocos mais genérico
- Rastreamento de caracteres enviados/recebidos, idealmente por chat.
- Estado, registro, etc por chat
Desenvolvimento
veja run_mcp_server.py.
Se você configurar o Claude Desktop como abaixo, poderá reiniciá-lo para ver as mudanças mais recentes enquanto trabalha no MCPunk a partir da sua versão local do repositório.
{
"mcpServers": {
"MCPunk": {
"command": "/Users/michael/.local/bin/uvx",
"args": [
"--from",
"/Users/michael/git/mcpunk",
"--no-cache",
"mcpunk"
]
}
}
}
Testes, Lint e CI
Consulte o Makefile e os workflows do GitHub Actions.