Scalable CTags

Servidor MCP CTags com autodescoberta, projetado para grandes projetos

Documentação

Servidor MCP para permitir navegação de código usando um arquivo de tags. Tem como objetivo lidar com arquivos de tags grandes com sobrecarga mínima.

Lars Hollenbach db4e896232 fix(server): register watcher with absolute path on manual load...

load_tags_file called o.watcher.Add(path) with the user-supplied path,
which can be relative. fsnotify reports events for that file under a
different key (the path the kernel gives back), so a relative-path load
could silently drop watcher events.

Use the absolute path returned by ParseTagsFile (pf.Path), which the index and discovery layer already canonicalise to. Add tests covering both plain and non-canonical (./tags) relative inputs.

AI-Assisted: written with opencode and MiniMax-M3

2026-08-05 04:00:18 +02:00
archived-planschore(plans): move auto-discovery to archive2026-07-14 22:34:30 +02:00
cmd/ctags-mcpfeat(server) Load discovered tags files in background worker pool2026-08-05 03:46:06 +02:00
internalfix(server): register watcher with absolute path on manual load2026-08-05 04:00:18 +02:00
testdata/tagsfeat: implement scalable CTags MCP server with memory-mapped file parsing2026-07-10 02:15:43 +02:00
.envrcfeat: implement scalable CTags MCP server with memory-mapped file parsing2026-07-10 02:15:43 +02:00
.gitignorechore: fix gitignore, add missing main.go2026-07-14 23:17:16 +02:00
AGENTS.mdfeat(server) Load discovered tags files in background worker pool2026-08-05 03:46:06 +02:00
flake.lockfeat: implement scalable CTags MCP server with memory-mapped file parsing2026-07-10 02:15:43 +02:00
flake.nixfeat: implement scalable CTags MCP server with memory-mapped file parsing2026-07-10 02:15:43 +02:00
go.modrefactor(parser,indexer,server) consolidate shared fields into CTagsEntry and strip filePaths + fileID from TagIndex2026-07-15 03:04:31 +02:00
go.sumrefactor(parser,indexer,server) consolidate shared fields into CTagsEntry and strip filePaths + fileID from TagIndex2026-07-15 03:04:31 +02:00
README.mdfeat(server) Load discovered tags files in background worker pool2026-08-05 03:46:06 +02:00

Servidor MCP Scalable CTags

Um servidor de busca de símbolos ctags com mapeamento de memória que expõe uma interface MCP (Model Context Protocol) para agentes de IDE e ferramentas de LLM. Projetado para lidar com múltiplos e grandes arquivos de tags em vários subprojetos.

Recursos

  • Suporte a múltiplos arquivos: Carregue e pesquise em vários arquivos de tags simultaneamente
  • Atualização automática: Observa arquivos carregados e atualiza automaticamente
  • Campos estendidos: Extrai kind, language e filePath do formato estendido v2 do ctags

Compilação

Requer Go 1.26+ e um ambiente Nix (ou toolchain Go padrão).

# With Nix (recommended)
nix develop --command go build -o ctags-mcp ./cmd/ctags-mcp

# Without Nix
go build -o ctags-mcp ./cmd/ctags-mcp

Arquivo de tags

Gere um arquivo de tags para o seu projeto antes de executar o servidor:

ctags -n -R .

A flag -n (--excmd=number) é obrigatória — ela instrui o ctags a armazenar números de linha em vez de padrões regex como comandos de busca. Sem ela, o servidor retorna line: 0 para todas as buscas de símbolos.

Execução

O servidor se comunica via stdio (JSON-RPC).

./ctags-mcp

Na inicialização, o servidor descobre automaticamente arquivos tags e tags.in do diretório de trabalho atual (até 8 níveis de profundidade) e os analisa em um pool de goroutines em segundo plano — o handshake do MCP responde imediatamente, não importa o tamanho dos arquivos de tags. As ferramentas de busca (lookup_symbol, get_symbol_info) bloqueiam até que o carregamento inicial seja concluído; list_tags_files responde imediatamente e relata status por arquivo (loading / ready) além de uma flag loadingComplete de nível superior. Diretórios ocultos (prefixados com ponto) são sempre ignorados. Use --auto-discover=false para desabilitar a descoberta automática completamente.

Por padrão, diretórios adicionais que correspondem à flag --skip-dirs (nomes de diretórios separados por vírgula) são excluídos (por exemplo, vendor, node_modules).

Configure a descoberta:

FlagPadrãoDescrição
--auto-discovertrueHabilita (true) ou desabilita (false) a descoberta automática
--depth8Níveis máximos de recursão abaixo do diretório de trabalho
--skip-dirs(nenhum)Nomes de diretórios separados por vírgula a serem excluídos

Uso no opencode

Adicione o servidor ao seu opencode.json sob a chave mcp:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "ctags": {
      "type": "local",
      "command": ["./ctags-mcp"],
      "enabled": true
    }
  }
}

Após editar opencode.json, saia e reinicie o opencode para que as alterações tenham efeito.

Ferramentas disponíveis

A resposta de load_tags_file inclui um campo preloaded definido como true quando o arquivo foi descoberto automaticamente na inicialização.

FerramentaDescriçãoParâmetros
load_tags_fileCarrega um arquivo de tags ctags e constrói o índicepath (obrigatório)
lookup_symbolBusca no índice por um símbolo pelo nome (bloqueia até que o carregamento inicial seja concluído)name (obrigatório), fileID (opcional)
get_symbol_infoObtém informações detalhadas sobre um único símbolo (bloqueia até que o carregamento inicial seja concluído)name (obrigatório), fileID (opcional)
list_tags_filesLista todos os arquivos de tags descobertos com metadados, status (loading / ready) e flag loadingCompletenenhum

Recursos disponíveis

URIDescrição
tagsfile://metadataMetadados JSON para um arquivo de tags carregado
file://{abspath}:{line}Conteúdo da linha de origem de uma entrada de tag

Exemplo de uso

Depois que o servidor estiver configurado no opencode, você pode fazer perguntas em linguagem natural e o agente usará as ferramentas:

"Find all references to AddTagsFile in the codebase"
"Show me detailed info about the EntryRef struct"
"What tags files are currently loaded?"
"Look up the Lookup function, filtering by fileID 0"

O agente chamará list_tags_files para verificar o que já está carregado e, em seguida, usará lookup_symbol ou get_symbol_info para responder. Para projetos sem um arquivo de tags no disco, ele chamará load_tags_file primeiro.

Arquitetura

internal/
  parser/       Streaming line-by-line ctags parser
  indexer/      In-memory index (map[string][]Entry); lock-free single-pass
                parsing (ParseTagsFile) with deferred merge (InstallParsed)
  server/       MCP protocol layer (Server) + index lifecycle
                (IndexOrchestrator: discovery, background load, watch/rebuild)
  cmd/ctags-mcp/  Entry point (stdio transport)