Srclight

Indexação profunda de código para agentes de IA — 25 ferramentas MCP: busca híbrida FTS5 + embeddings, grafos de chamada, git blame/hotspots, análise de sistema de build. Workspaces multi-repositório, busca semântica acelerada por GPU, 10 linguagens. Totalmente local, zero dependências de nuvem.

Documentação

Srclight

PyPI License Python

Indexação profunda de código para agentes de IA. SQLite FTS5 + tree-sitter + embeddings + MCP.

O Srclight constrói um índice rico e pesquisável do seu código que agentes de IA podem consultar instantaneamente — substituindo dezenas de chamadas grep/glob por buscas precisas e estruturadas. É o servidor MCP de inteligência de código mais abrangente disponível: 42 ferramentas cobrindo busca de símbolos, grafos de relacionamento, detecção de comunidades, análise de impacto, inteligência de mudanças git, busca semântica, ciência de sistemas de build e extração de documentos — capacidades que nenhum outro servidor MCP combina. Totalmente local e privado: seu código nunca sai da sua máquina.

Por quê?

Agentes de IA de codificação (Claude Code, Cursor, etc.) gastam 40-60% dos seus tokens em orientação — procurando arquivos, lendo código para entender estrutura, caçando chamadores e chamados. O Srclight elimina esse desperdício.

Sem SrclightCom Srclight
8-12 rodadas de grep para encontrar chamadoresget_callers("lookup") — uma chamada
Ler 5 arquivos para entender um módulocodebase_map() — visão instantânea
"Encontrar código que faz X" → 20 grepssemantic_search("dictionary lookup") — uma chamada
Editar uma função, quebrar 47 chamadoresdetect_changes() — mostra o raio de impacto antes de você commitar
15-25 chamadas de ferramenta por correção de bug5-8 chamadas de ferramenta por correção de bug

Recursos

  • Dependências mínimas — um único arquivo SQLite por repositório, sem Docker/Redis/banco vetorial
  • Totalmente offline — sem chamadas de API, funciona em ambiente isolado (embeddings locais com Ollama)
  • Incremental — reindexa apenas arquivos alterados (detecção por hash de conteúdo)
  • 19 linguagens — Python, C, C++, C#, Java, Kotlin, Swift, Dart, Go, Rust, JavaScript, TypeScript, PHP, Lua, Bash, SQL, Groovy, CMake, Markdown — fragmentos de inclusão (.inc, .inl, .ipp, .tcc) incluídos, além de qualquer extensão que você declarar com --ext
  • Diz o que pulou — index_status nomeia as extensões que uma execução ignorou, para que uma resposta incompleta nunca pareça completa
  • 10 formatos de documento — PDF, DOCX, XLSX, HTML, CSV/TSV, e-mail (.eml), imagens (PNG/JPG/SVG/etc.), texto puro, RST, Markdown
  • OCR opcional — PaddleOCR para páginas PDF escaneadas/somente imagem; pytesseract para imagens
  • 4 modos de busca — nomes de símbolos, código-fonte (trigrama), documentação (stemming), semântica (embeddings)
  • Busca híbrida — fusão RRF de resultados de palavras-chave + semânticos para melhor precisão
  • Workspaces multi-repositório — busque em todos os seus repositórios simultaneamente via SQLite ATTACH+UNION
  • Servidor MCP — funciona com Claude Code, Cursor e qualquer cliente MCP
  • CLI — indexe, busque e inspecione pelo terminal
  • Reindexação automática — hooks git pós-commit/pós-checkout mantêm os índices atualizados

Validação de argumentos MCP

O servidor MCP do Srclight recusa argumentos de ferramenta desconhecidos em vez de descartá-los silenciosamente — um filtro digitado errado como projects= (para project=) é rejeitado com um erro, nunca respondido como se a restrição tivesse sido aplicada. Cada ferramenta anuncia additionalProperties: false. A proteção é a política compartilhada mcpkit, fornecida como um único arquivo verificado por hash (src/srclight/_mcpkit.py).

Agentes de IA: se uma chamada retornar unknown argument(s): … running older code than you think … reconnect, o servidor em execução é anterior ao argumento que você enviou (um daemon de longa duração serve o código com o qual foi iniciado). Nada foi executado — verifique a revisão informada e reconecte o MCP; não tente a mesma chamada novamente.

Atualização do índice

Todo resultado de símbolo/grafo carrega index_freshness: a string curta "verified-fresh" quando os arquivos por trás da resposta são byte-idênticos ao que foi indexado, ou um objeto limitado nomeando quais arquivos estão stale, ausentes ou não indexados. check_freshness(paths?) testa quaisquer caminhos — ou o índice inteiro — sob demanda (arquivos inalterados custam um stat cada; nunca grava), e index_status reporta checked/stale_count do índice inteiro.

Agentes de IA: um resultado marcado como desatualizado descreve o código como indexado, não como está agora — reindexe (srclight index) ou leia o arquivo ao vivo antes de agir com base em números de linha ou corpos dele. "verified-fresh" é o sinal afirmativo; sua ausência em um resultado em modo workspace significa que a atualização não pôde ser verificada para aquele resultado, nunca que ele está atualizado.

Cobertura do índice

index_status reporta ambos os lados do que um índice contém: indexed_extensions, todos os sufixos que ele lê, e unindexed_extensions, o {extension: file count} que este repositório contém e que a última execução ignorou, além de oversize_skipped para arquivos recusados por tamanho e failed_files para arquivos que não puderam ser lidos ou analisados. list_projects carrega o mesmo por projeto, e find_pattern anexa a contagem mais uma nota sempre que ela não estiver vazia.

Uma lacuna significa código que nunca foi lido, então a contagem deliberadamente deixa de fora o que é pulado de propósito: caminhos ignorados (binários, árvores vendidas, .git) tanto no modo git ls-files quanto no modo de varredura de diretórios, e sufixos inertes — configuração, dados e manifestos (.json, .toml, .yml, .lock, …) junto com arquivos sem sufixo como LICENSE ou Dockerfile. Todo repositório carrega alguns desses; contá-los deixaria a contagem não vazia em todo lugar, colocaria o aviso em todo resultado e enterraria as extensões que realmente contêm código não lido. Um formato de documento que esta instalação não consegue ler por falta de um extra (.pdf, .docx, .xlsx, .html) É contado — ele não foi lido, e está a um pip install de ser lido. O mesmo vale para uma extensão de código-fonte que a lista de ignorados bloqueia de qualquer forma (*.cmake fica ao lado dos artefatos de build enquanto cmake é uma linguagem que o srclight analisa), e uma linguagem cuja gramática tree-sitter não está instalada — indexar esses arquivos os registraria como lidos enquanto não contêm símbolo pesquisável.

truncated em um resultado find_pattern significa que a página foi cortada, e nada mais. Nunca descreveu cobertura de varredura: a busca roda sobre símbolos indexados, então arquivos que o indexador nunca leu não podem aparecer, diga o que disser. Uma lacuna agora é legível a partir do índice em vez de ser descoberta apenas comparando um resultado a um grep.

Fragmentos de inclusão (.inc, .inl, .ipp, .tcc) — os arquivos que um projeto usa para dividir uma unidade de tradução grande demais, incluídos no escopo do arquivo e contendo definições reais — são indexados como código-fonte. .inc nomeia uma convenção de inclusão em vez de uma linguagem, então seu conteúdo decide: PHP, C++, senão C.

Para uma extensão caseira que o srclight não conhece, declare-a uma vez:

srclight index --ext .zz=cpp          # repeatable; --ext none clears
srclight index --ext .inc=skip        # or: leave an extension unread

skip é a saída da detecção .inc para um projeto que a usa para fragmentos Makefile ou SQL: esses arquivos então contam como uma lacuna declarada em vez de serem analisados como C.

A declaração é armazenada no índice, não na linha de comando, então as reindexações sem flags dos hooks git continuam lendo esses arquivos.

Agentes de IA: um unindexed_extensions não vazio significa que a resposta que você está segurando não é uma resposta de árvore inteira, diga o que truncated disser — verifique com grep, ou faça a extensão ser declarada. Um vazio é o sinal afirmativo.

Rótulos de resolução de grafo

Arestas de referência são construídas por correspondência de nomes mais evidência ranqueada, e toda aresta de chamador/chamado carrega um rótulo resolution dizendo como seu alvo foi escolhido: same_file (o próprio arquivo do chamador define o nome), unique_file (todos os candidatos com o mesmo nome vivem em um arquivo), import (os imports do chamador isolam um arquivo), same_dir, ou name_only. Nomes que aparecem apenas em comentários ou strings nunca viram arestas.

Agentes de IA: name_only significa uma lista de candidatos ranqueada entre símbolos com o mesmo nome — leia como "um destes", não um link confirmado; verifique com get_symbol ou uma busca de referência antes de agir. Os rótulos mais fortes são seguros para tratar como resolvidos.

Requisitos

  • Python 3.11+
  • Git (para inteligência de mudanças e hooks de reindexação automática)
  • Ollama (opcional, para busca semântica / embeddings) — ollama.com
  • GPU NVIDIA + cupy (opcional, para busca vetorial acelerada por GPU)
  • Poppler (opcional, para suporte a PDF escaneado com PaddleOCR) — apt install poppler-utils / brew install poppler

Início Rápido

# Install from PyPI
pip install srclight

# Install from source
git clone https://github.com/srclight/srclight.git
cd srclight
pip install -e .

# Optional: document format support (PDF, DOCX, XLSX, HTML, images)
pip install 'srclight[docs,pdf]'

# Optional: OCR for scanned PDFs (also needs poppler-utils on your system)
pip install 'srclight[pdf,paddleocr]'

# Optional: OCR for images (needs tesseract on your system)
pip install 'srclight[docs,ocr]'

# Optional: GPU-accelerated vector search (requires CUDA 12.x)
pip install 'srclight[gpu]'

# Everything (docs + pdf + ocr + paddleocr + gpu)
pip install 'srclight[all]'

# Index your project
cd /path/to/your/project
srclight index

# Index with embeddings (requires Ollama running)
srclight index --embed qwen3-embedding

# Read an extra extension as a known language (recorded in the index)
srclight index --ext .inc=cpp

# Search
srclight search "lookup"
srclight search --kind function "parse"
srclight symbols src/main.py

# Start MCP server (for Claude Code / Cursor)
srclight serve

Nota: srclight index mantém .srclight/ fora do git através do .git/info/exclude local do repositório (nunca edita seu .gitignore rastreado). Bancos de dados de índice e arquivos de embedding podem ser grandes e nunca devem ser commitados.

Executando ferramentas pelo shell

Toda ferramenta MCP é acessível pela CLI, que é como um agente com sandbox pode consultar o índice sem que a resposta entre no seu contexto:

srclight tool --list                    # every tool and what it does
srclight tool find_pattern --help       # arguments, from the tool's own schema
srclight tool find_pattern --pattern 'this->timer' --kind function --limit 80

A saída é o JSON da ferramenta no stdout e nada mais, então ela pode ser canalizada. Códigos de saída são 0 em sucesso, 1 quando a ferramenta reporta um erro, 2 em erro de uso — um erro de uso não escreve nada no stdout e diz o motivo no stderr.

O comando lê o registro de ferramentas do próprio servidor, então sempre corresponde às ferramentas que seu cliente MCP vê — e uma ferramenta renomeada no lado MCP também é renomeada aqui.

Busca Semântica (Embeddings)

O Srclight suporta busca semântica baseada em embeddings para consultas em linguagem natural como "encontre código que lida com autenticação" ou "onde está o pool de conexões do banco de dados".

Configuração

# Install Ollama (https://ollama.com)
# Pull an embedding model
ollama pull qwen3-embedding       # Best quality (8B params, needs ~6GB VRAM)
ollama pull nomic-embed-text      # Lighter alternative (137M params)

# Index with embeddings
srclight index --embed qwen3-embedding

# Or index workspace with embeddings
srclight workspace index -w myworkspace --embed qwen3-embedding

Escolhendo o Modelo Uma Vez

--embed só precisa ser passado uma vez por índice. O índice registra o modelo e toda execução posterior o reutiliza — incluindo o srclight index . sem flags que os hooks git executam a cada commit, e a ferramenta MCP reindex. Sem isso, todo símbolo adicionado após a primeira execução permanece sem embedding até que alguém lembre da flag.

srclight index --embed qwen3-embedding   # first run: records the model
srclight index                           # later runs: reuse it, no flag

O nome registrado é qualificado por provedor, então a segunda execução reporta Embedding model: ollama:qwen3-embedding (from the existing index).

Para índices que não têm modelo registrado ainda, SRCLIGHT_EMBED_MODEL fornece um:

export SRCLIGHT_EMBED_MODEL=qwen3-embedding
srclight index                           # a fresh index embeds with it

A ordem de resolução é --embed > o modelo registrado no índice > SRCLIGHT_EMBED_MODEL. A variável vem por último de propósito: é um padrão para novos índices, nunca uma sobrescrita. Antes do modelo registrado, exportá-la uma vez faria o próximo commit em um repositório não relacionado re-embeddar todo símbolo que ele contém, silenciosamente, a partir de um hook em segundo plano. Trocar um índice existente continua sendo um --embed explícito.

Duas saídas de emergência:

srclight index --no-embed             # skip embedding for this run only
srclight index --forget-embed-model   # stop embedding this index for good

--forget-embed-model é o interruptor de desligamento para os hooks, cuja linha de comando é fixa: depois dele, commits indexam sem nunca chamar o modelo de embedding, até você passar --embed novamente. Pelo MCP, reindex(embed=False) é o equivalente por chamada de --no-embed.

Note que pular não é grátis. Reindexar um arquivo alterado descarta os embeddings dos símbolos que ele substitui, e uma passada pulada não os coloca de volta — a cobertura semântica decai exatamente nos arquivos sendo editados. Pergunte ao embedding_status() o que um índice fará: configured_model é o modelo que a próxima execução sem flags resolve — a cadeia inteira, variável de ambiente incluída — e null significa que não vai embeddar. Apenas modo repositório único: em um workspace cada projeto registra o seu, então o campo não é reportado.

Como Funciona

  1. O nome + assinatura + docstring + conteúdo de cada símbolo é embeddado como um vetor float
  2. Vetores são armazenados como BLOBs na tabela symbol_embeddings (SQLite)
  3. Após a indexação, um snapshot sidecar .npy é construído e carregado na VRAM da GPU (cupy) ou RAM da CPU (numpy) para busca rápida
  4. semantic_search(query) embedda a consulta e executa similaridade de cosseno contra a matriz residente na GPU (~3ms para 27K vetores em uma GPU moderna)
  5. hybrid_search(query) combina resultados de palavras-chave FTS5 + resultados de embedding via Fusão por Rank Recíproco (RRF)

Provedores de Embedding

ProvedorModeloQualidadeLocal?Notas
Ollama (padrão)qwen3-embeddingMelhor localSimPrecisa de ~6GB de VRAM
Ollamanomic-embed-textBomSimMais leve, funciona com 8GB de VRAM
Voyage AI (API)voyage-code-3Melhor no geralNãoRequer VOYAGE_API_KEY
# Use Voyage Code 3 (API, highest quality)
VOYAGE_API_KEY=your-key srclight index --embed voyage-code-3

Armazenamento

Os embeddings são armazenados na tabela symbol_embeddings em .srclight/index.db. Após a indexação, um snapshot sidecar .npy é construído para carregamento rápido na GPU:

ArquivoFinalidade
index.dbCaminho de escrita — CRUD por símbolo durante a indexação
embeddings.npyCaminho de leitura — matriz float32 contígua para busca em GPU/CPU
embeddings_norms.npyNormas de linha pré-computadas (evita recomputação por consulta)
embeddings_meta.jsonMapeamento de ID de símbolo, informações do modelo, versão para invalidação de cache

Para ~27 mil símbolos com 4096 dimensões (qwen3-embedding), isso representa ~428 MB em disco, ~450 MB em VRAM. Incremental: apenas símbolos cujo conteúdo mudou são re-embeddados; o sidecar é reconstruído após cada execução de indexação.

Espaços de Trabalho Multi-Repositório

Busque em vários repositórios simultaneamente. Cada repositório mantém seu próprio .srclight/index.db; no momento da consulta, o srclight os ANEXA a todos e faz UNION entre os esquemas.

# Create a workspace
srclight workspace init myworkspace

# Add repos
srclight workspace add /path/to/repo1 -w myworkspace
srclight workspace add /path/to/repo2 -w myworkspace -n custom-name

# Index all repos (with optional embeddings)
srclight workspace index -w myworkspace
srclight workspace index -w myworkspace --embed qwen3-embedding

# Search across all repos
srclight workspace search "Dictionary" -w myworkspace
srclight workspace search "Dictionary" -w myworkspace --project repo1

# Status
srclight workspace status -w myworkspace
srclight workspace list

# Start MCP server in workspace mode
srclight serve --workspace myworkspace

Submódulos Git não são indexados automaticamente — git ls-files não faz recursão neles. Para indexar um submódulo, clone-o separadamente e adicione-o como um projeto próprio do espaço de trabalho. Consulte docs/usage-guide.md para detalhes.

Integração MCP

O Srclight suporta dois modos de transporte: stdio (um servidor por sessão) e SSE (servidor persistente, múltiplas sessões). SSE é recomendado para espaços de trabalho.

Claude Code

Stdio (mais simples — um servidor por sessão):

# Single repo
claude mcp add srclight -- srclight serve

# Workspace mode
claude mcp add srclight -- srclight serve --workspace myworkspace

# Make it available in all projects (user scope)
claude mcp add --scope user srclight -- srclight serve --workspace myworkspace

SSE (servidor persistente — recomendado para espaços de trabalho):

Execute o srclight como um servidor de longa duração e aponte o Claude Code para ele:

# Start the server (default: http://127.0.0.1:8742/sse)
srclight serve --workspace myworkspace &

# Or install as a systemd user service (Linux/WSL)
# See docs/usage-guide.md for the service file

# Connect Claude Code to the running server
claude mcp add --transport sse srclight http://127.0.0.1:8742/sse

O modo SSE suporta múltiplas sessões concorrentes e sobrevive a reinicializações do Claude Code.

Cursor

SSE (recomendado): Execute o srclight uma vez e conecte o Cursor a ele. Melhor para responsividade e sem cold-start por sessão.

Inicie o servidor: srclight serve --workspace myworkspace (SSE padrão na porta 8742).

  • UI: Configurações → Tools & MCP → Adicionar novo servidor MCP → Tipo: streamableHttp, URL: http://127.0.0.1:8742/sse.
  • JSON (.cursor/mcp.json do projeto ou ~/.cursor/mcp.json global):
"srclight": {
  "url": "http://127.0.0.1:8742/sse"
}

Stdio (alternativa): Um processo de servidor por sessão do Cursor.

  • UI: Tipo: command, Comando: srclight, Argumentos: serve --workspace myworkspace (ou serve para repositório único).
  • JSON:
"srclight": {
  "command": "srclight",
  "args": ["serve", "--workspace", "myworkspace"]
}

Para repositório único: "args": ["serve"]. Reinicie o Cursor completamente após adicionar o servidor.

Verificação: No chat do Cursor, pergunte "Quais projetos estão no espaço de trabalho do srclight?" ou "Liste as ferramentas do srclight" — o agente deve chamar list_projects() ou mostrar as ferramentas do srclight.

OpenClaw

O OpenClaw conecta-se ao srclight via mcporter, sua CLI integrada de servidor de ferramentas MCP.

# 1. Add srclight to mcporter's home config
mcporter config add srclight http://127.0.0.1:8742/sse \
  --transport sse --scope home \
  --description "Srclight deep code indexing"

# 2. Verify the connection
mcporter call srclight.list_projects

# 3. Restart the OpenClaw gateway to pick up the new server
systemctl --user restart openclaw-gateway  # if using systemd
# or: openclaw daemon restart

O agente OpenClaw pode então usar as ferramentas do srclight por meio da habilidade mcporter:

mcporter call srclight.search_symbols query="my_function"
mcporter call srclight.get_callers symbol_name="MyClass" project="my-repo"
mcporter call srclight.hybrid_search query="authentication logic"

Pré-requisito: O Srclight deve estar em execução como servidor SSE (veja acima). O mcporter do OpenClaw conecta-se via HTTP — o modo stdio não é suportado.

Claude Desktop (claude_desktop_config.json)

{
  "mcpServers": {
    "srclight": {
      "command": "srclight",
      "args": ["serve", "--workspace", "myworkspace"]
    }
  }
}

Qualquer Cliente MCP (SSE)

Qualquer cliente compatível com MCP pode conectar-se ao endpoint SSE:

http://127.0.0.1:8742/sse

Ferramentas MCP (43)

O Srclight expõe 43 ferramentas MCP organizadas em oito níveis. O servidor MCP inclui instruções integradas que orientam agentes de IA sobre qual ferramenta usar e quando — os agentes recebem um protocolo de sessão, guia de seleção de ferramentas e documentação de parâmetros project automaticamente na conexão.

Nível 1: Orientação Instantânea

FerramentaO que faz
codebase_map()Visão geral completa do projeto — chame primeiro em cada sessão
search_symbols(query)Busca em nomes de símbolos, código e documentação
get_symbol(name)Código-fonte completo + metadados de um símbolo
get_signature(name)Apenas a assinatura (leve)
symbols_in_file(path)Sumário de um arquivo
find_pattern(pattern, limit, offset)Busca regex dentro dos corpos dos símbolos; informa quando truncou
list_projects()Todos os projetos no espaço de trabalho com estatísticas

Nível 2: Grafo de Relacionamentos

FerramentaO que faz
get_callers(name)Quem chama este símbolo?
get_callees(name)O que este símbolo chama?
get_dependents(name, transitive)Raio de impacto — o que quebra se eu mudar isto?
get_implementors(interface)Todas as classes que implementam uma interface
get_tests_for(name)Funções de teste que cobrem um símbolo
get_type_hierarchy(name)Árvore de herança (classes base + subclasses)
find_imports(path)Declarações de import em um arquivo, resolvidas para arquivos indexados
find_dead_code(kind)Símbolos que nada chama ou referencia

Nível 2b: Análise de Comunidade e Impacto

FerramentaO que faz
get_communities(project)Clusters de módulos funcionais detectados automaticamente (algoritmo de Louvain)
get_community(name, project)A qual comunidade um símbolo pertence, com todos os co-membros
get_execution_flows(project)Caminhos de execução rastreados desde pontos de entrada pelo grafo de chamadas
get_impact(name, project)Raio de impacto + nível de risco (BAIXO / MÉDIO / ALTO / CRÍTICO)
detect_changes(project, ref?)Mapeia git diff para símbolos afetados — raio de impacto agregado das suas edições

Nível 3: Inteligência de Mudanças Git

FerramentaO que faz
blame_symbol(name)Quem mudou isto, quando e por quê
recent_changes(n)Feed de commits (entre projetos no espaço de trabalho)
git_hotspots(n, since)Arquivos alterados com mais frequência (ímãs de bugs)
whats_changed()Trabalho em andamento não commitado
changes_to(name)Histórico de commits do arquivo de um símbolo

Nível 4: Build e Configuração

FerramentaO que faz
get_build_targets()Alvos CMake/.csproj/npm com dependências
get_platform_variants(name)Proteções de plataforma #ifdef ao redor de um símbolo
platform_conditionals()Todos os blocos de código condicionais por plataforma

Nível 5: Busca Semântica (Embeddings)

FerramentaO que faz
semantic_search(query)Encontre código por significado (linguagem natural)
hybrid_search(query)O melhor dos dois: palavra-chave + semântico com fusão RRF
embedding_status()Cobertura de embeddings e informações do modelo

Nível 6: Meta e Servidor

FerramentaO que faz
index_status()Atualidade do índice e estatísticas
check_freshness(paths)O índice está atualizado para estes arquivos, ou para todos eles?
show_status(message)Mostra a janela do painel do srclight e retorna o status atual
reindex(embed=True)Dispara re-indexação incremental; embed=False pula a etapa de embeddings (e deixa a cobertura semântica degradar)
embedding_health()Verifica se o provedor de embeddings (Ollama, etc.) está acessível
setup_guide()Instruções de configuração estruturadas para agentes e usuários
server_stats()Tempo de atividade do servidor e informações do processo
restart_server()Solicita reinicialização do servidor (apenas SSE)

Nível 7: Aprendizados e Memória de Sessão

FerramentaO que faz
record_learning(kind, content)Registra uma decisão, correção, descoberta, padrão, bloqueio ou convenção
relevant_learnings(query)Encontra aprendizados registrados por palavra-chave + busca semântica
learning_stats(days)Contagens por tipo ao longo do tempo
conversation_summary(session_id, task_summary)Registra o que uma sessão fez, com números de tokens e custos

No modo espaço de trabalho, search_symbols, get_symbol, codebase_map e hybrid_search aceitam um filtro opcional project. Ferramentas de grafo/git/build/comunidade exigem project no modo espaço de trabalho.

Validação Estrita de Argumentos

Desde a v0.20.2, o srclight recusa argumentos de ferramenta desconhecidos em vez de descartá-los silenciosamente. Esta é uma mudança de comportamento deliberada e pode quebrar chamadores que antes enviavam chaves extras sem perceber.

Por quê

O FastMCP do SDK Python do MCP descarta argumentos que não estão na assinatura de uma ferramenta, e o faz antes de a função da ferramenta ser executada. Combinado com um inputSchema que omitia additionalProperties: false, um argumento digitado incorretamente produzia uma resposta errada e confiante em vez de um erro. Medido neste servidor:

search_symbols(query="main", project="project-a")    ->  20 hits, all from project-a
search_symbols(query="main", projects="project-a")   ->  20 hits, ZERO from project-a
                                                         (19 from "project-b", 1 from "project-c")

Uma letra adicionada. Sem erro, contagem de resultados idêntica, formato de resultado idêntico, símbolos reais — de repositórios sobre os quais o chamador nunca perguntou. Isso não é uma chamada com perda, é uma chamada errada, e o chamador não tem como saber que seu filtro foi ignorado.

O que mudou

  • Argumentos desconhecidos agora retornam um erro nomeando a chave ofensiva, o conjunto aceito e informando que nada foi executado. O corpo da ferramenta nunca é acessado.
  • Toda ferramenta anuncia additionalProperties: false em tools/list, para que o catálogo corresponda ao que o runtime impõe. Antes, o runtime e o esquema anunciado discordavam.
  • Ferramentas de zero parâmetros também são fechadas (index_status, codebase_map e outras três). Um conjunto de propriedades vazio significa "esta ferramenta não aceita argumentos", não "qualquer coisa vale".

Escopo: argumentos de nível superior

Isto valida o objeto de argumento de nível superior. Um argumento que é em si um objeto estruturado é validado pelo seu próprio modelo, no qual esta camada não desce. Nenhuma ferramenta do srclight atualmente aceita um argumento de objeto, então a distinção não é alcançável aqui hoje — mas a garantia é "nível superior", e uma ferramenta futura que aceite um modelo aninhado tipado precisaria de extra="forbid" nesse modelo para obter a mesma proteção.

Se isto quebrar seu chamador

O erro nomeia exatamente o que recebeu e o que a ferramenta aceita:

unknown argument(s): projects. Tool 'search_symbols' accepts: kind, limit, project, query.
Nothing was executed and no result was computed.

Corrija o nome do argumento. Se você acredita que o argumento deveria existir, o servidor pode estar executando código mais antigo do que você espera — verifique a revisão informada e reconecte-se.

Se você não puder atualizar seu chamador agora, fixe o comportamento anterior e atualize quando puder:

pip install "srclight<0.20.2"

Isso é uma saída de emergência deliberada, não um endosso — as versões mais antigas ainda retornam respostas erradas para filtros digitados incorretamente, silenciosamente. Prefira corrigir o nome do argumento.

Para contribuidores

A política reside em src/srclight/_mcpkit.py, um build de arquivo único gerado de mcpkit, compartilhado entre os servidores MCP deste ecossistema para que uma política não seja reimplementada por repositório. Não edite manualmente — ele carrega um sha256 do próprio corpo e um verificador rejeitará uma cópia modificada.

python -m mcpkit.vendor --out src/srclight/_mcpkit.py    # regenerate from upstream
python -m mcpkit.vendor --check src/srclight/_mcpkit.py  # verify it is unmodified

Ele adiciona nenhuma dependência de runtime — o arquivo é vendido, não instalado, então pip install srclight não é afetado. O mcpkit só é necessário para regenerá-lo.

tests/test_strict_args.py é um teste de fumaça que afirma que srclight.server.mcp em si aplica a política — não um sósia recém-construído. Se server.py fosse revertido para um FastMCP simples enquanto _mcpkit.py ficasse sem uso na árvore, esse teste seria o único que falharia.

Guia de Implantação

Consulte docs/usage-guide.md para o guia completo de implantação e uso, incluindo:

  • Configurando o srclight como um servidor MCP global para o Claude Code
  • Adicionando/removendo repositórios de espaços de trabalho
  • O que acontece em commits e trocas de branch
  • Fluxos de trabalho de re-embedding
  • Solução de problemas

Reindexação Automática (Hook Git)

Mantenha os índices atualizados automaticamente:

# Install post-commit + post-checkout hooks in current repo
srclight hook install

# Install across all repos in a workspace
srclight hook install --workspace myworkspace

# Remove hooks
srclight hook uninstall

Os hooks executam srclight index em segundo plano após cada commit e troca de branch. Em um repositório cujo índice tem um modelo de embeddings registrado, isso também atualiza os embeddings — consulte Escolhendo o Modelo Uma Vez para o interruptor de desligamento.

Como Funciona

  1. tree-sitter analisa cada arquivo de código-fonte em uma AST
  2. Extratores de documentos lidam com arquivos não-código (PDF, DOCX, XLSX, HTML, CSV, imagens, e-mail, texto) — extraindo cabeçalhos, tabelas, páginas e metadados como símbolos pesquisáveis. Páginas de PDF escaneadas são opcionalmente submetidas a OCR via PaddleOCR.
  3. Símbolos (funções, classes, métodos, structs, etc.) são extraídos com metadados completos
  4. Três índices SQLite FTS5 são construídos com diferentes estratégias de tokenização:
    • Nomes: tokenização ciente de código (divide camelCase, lida com ::, ->)
    • Conteúdo: índice trigrama para correspondência de substrings
    • Docs: stemming de Porter para linguagem natural em docstrings
  5. Detecção de comunidades agrupa símbolos em módulos funcionais via algoritmo de Louvain nas arestas do grafo de chamadas, com rotulagem automática TF-IDF
  6. Fluxos de execução são rastreados via BFS a partir de pontos de entrada, e a análise de impacto pontua o raio de explosão de cada símbolo (BAIXO/MÉDIO/ALTO/CRÍTICO)
  7. Opcional: vetores de incorporação são gerados via API Ollama ou Voyage e armazenados como BLOBs
  8. Um snapshot sidecar .npy é construído e carregado na VRAM da GPU (cupy) ou RAM da CPU (numpy) para busca rápida
  9. O servidor MCP expõe ferramentas de consulta estruturada que agentes de IA chamam em vez de grep
  10. Busca híbrida mescla resultados de palavras-chave (FTS5) e semânticos (incorporação) via RRF

Arquitetura (Modo Workspace)

repo1/.srclight/index.db  ──┐
repo2/.srclight/index.db  ──┼── ATTACH ──→ :memory: ──→ UNION ALL queries
repo3/.srclight/index.db  ──┘

Cada repositório é indexado de forma independente. No momento da consulta, o mecanismo ATTACH do SQLite os une em um único namespace pesquisável. Lida com mais de 10 repositórios via agrupamento automático (limite de ATTACH do SQLite).

Como o Srclight se Compara

Uma pesquisa com mais de 50 servidores de inteligência de código MCP em todos os principais registros (Official MCP Registry, Smithery, Glama, mcp.so, awesome-mcp-servers) descobriu que nenhum outro servidor único combina todos os recursos do srclight:

Capacidadesrclightgrep/glob (padrão)CodeMCP (SCIP)Claude Context (Zilliz)
Busca de símbolos (FTS5)3 índices (nome, conteúdo, docs)NenhumBaseado em SCIPBM25
Busca semântica (incorporações)Acelerada por GPU, ~3msNenhumNenhumAPI OpenAI + Milvus
Busca híbrida (palavras-chave + semântica)Fusão RRFNenhumNenhumBM25 + vetor
Grafo de relacionamentos (chamadores, chamados)Arestas tree-sitterNenhumArestas SCIPNenhum
Detecção de comunidades (agrupamentos de módulos)Louvain no grafo de chamadasNenhumNenhumNenhum
Análise de impacto (raio de explosão + risco)Por símbolo + nível de diffNenhumNenhumNenhum
Inteligência de mudanças Gitblame, hotspots, WIP, detect_changesNenhumNenhumNenhum
Consciência do sistema de buildCMake, .csproj, #ifdefNenhumNenhumNenhum
Workspace multi-repositórioATTACH+UNIONNenhumNenhumNenhum
Infraestrutura necessáriapip install, SQLiteNenhumIndexador SCIPDocker, Milvus, API OpenAI
Totalmente local / privadoSim, zero chamadas de APISimSimNão (precisa de OpenAI)
Linguagens19Qualquer (regex)5 (SCIP)Qualquer (chunking)
Ferramentas MCP432 (grep, glob)80+~10

Ao contrário de ferramentas baseadas em grep, o srclight constrói um índice persistente com consultas estruturadas. Ao contrário de soluções baseadas em nuvem, tudo roda localmente — seu código nunca sai da sua máquina. Ao contrário de plugins de IDE, o srclight funciona com qualquer cliente MCP.

Roadmap

Concluído

  • Inteligência de símbolos + busca 3x FTS5
  • Grafo de relacionamentos: chamadores, chamados, hierarquia
  • Raio de explosão, descoberta de testes, implementadores
  • Inteligência de mudanças Git: blame, hotspots, mudanças recentes
  • Consciência do sistema de build: CMake, .csproj, condicionais de plataforma
  • Busca semântica: incorporações via Ollama/Voyage, RRF híbrido
  • Busca vetorial acelerada por GPU: sidecar .npy, matemática vetorizada cupy/numpy
  • Workspaces multi-repositório (ATTACH+UNION)
  • Hooks Git de reindexação automática (post-commit + post-checkout)
  • Extração de documentos: PDF, DOCX, XLSX, HTML, CSV, e-mail, imagens, texto (detecção de cabeçalhos, tabelas, metadados)
  • OCR opcional: PaddleOCR para PDFs escaneados, pytesseract para imagens
  • Orientação do agente MCP: instruções abrangentes, guia de seleção de ferramentas, protocolo de sessão
  • Recarga a quente da configuração do workspace (sem necessidade de reiniciar o servidor para adicionar repositórios)
  • Redescoberta do sidecar VectorCache (sem reinício necessário após incorporação)
  • Sugestões de nomes de projetos em mensagens de erro
  • Detecção de comunidades: agrupamento Louvain nas arestas do grafo de chamadas com rotulagem automática TF-IDF
  • Rastreamento de fluxo de execução: BFS a partir de pontos de entrada através de limites de comunidades
  • Análise de impacto: raio de explosão por símbolo com pontuação de risco (BAIXO/MÉDIO/ALTO/CRÍTICO)
  • detect_changes: mapear git diff para símbolos afetados e agregar raio de explosão

Próximos

  • Mapeamento de conceitos entre linguagens (arestas explícitas entre símbolos equivalentes entre linguagens)
  • Inteligência de padrões (detecção de convenções, extração de padrões de código)
  • Pré-computação de IA (resumos de símbolos via LLM barato)

Licença

MIT — Gig8 LLC