O servidor MCP do ank

Cada verbo da CLI como uma ferramenta, para um cliente sem shell. Uma linha para adicioná-lo ao Claude Code:

claude mcp add ank -- ank mcp --repo /path/to/your/repo

O que é o ank mcp

ank mcp é um verbo do único executável que toda forma de instalação coloca. Não há um segundo arquivo para baixar: o que a CLI despacha é o que o servidor serve, porque são o mesmo binário.

Ele fala JSON-RPC sobre stdio, e quem o inicia é o cliente. Então você não o sobe, você o configura: um comando, seus argumentos e o repositório em nome do qual ele fala.

Configurar um cliente

A entrada é o mesmo JSON nos três clientes. Só muda o arquivo onde ela vai.

.mcp.json · a entrada
{
  "mcpServers": {
    "ank": {
      "command": "ank",
      "args": ["mcp", "--repo", "/path/to/your/repo"]
    }
  }
}

Onde ela vai

Claude Code
.mcp.json na raiz do repositório, a forma que viaja com o tree e chega a todo mundo que o clona. Ou a linha claude mcp add acima, que escreve a entrada para você.
Claude Desktop
claude_desktop_config.json, em ~/Library/Application Support/Claude/ no macOS e em %APPDATA%\Claude\ no Windows.
Cursor
.cursor/mcp.json ao lado do repositório, ou ~/.cursor/mcp.json para todos os projetos de uma vez.

O comando é ank, e mcp o primeiro argumento

Até a 0.6.0, as releases colocavam um segundo executável chamado ank-mcp. Nenhuma forma de instalação o coloca mais, então uma configuração que ainda o nomeia recebe command not found. É a única linha a mudar.

Sempre escreva --repo

Um cliente inicia o servidor no diretório em que estiver, e sem --repo o servidor assume esse diretório. A falha não é um erro: é um processo falando, quietinho, em nome de um corpus que ninguém quis, ou de nenhum. Um caminho sem .ank/ é recusado na inicialização, onde uma pessoa vê.

ank mcp
ank mcp --repo /tmp
error[1]: no .ank/ found from /tmp
  -> ank init

Cada verbo, uma ferramenta

As ferramentas são geradas a partir da mesma tabela que o binário despacha e que ank help --json descreve. Não é um subconjunto escolhido a dedo: as duas superfícies não têm como discordar sobre o que existe.

  • ank_context
  • ank_claim
  • ank_show
  • ank_log
  • ank_done
  • ank_release
  • ank_new
  • ank_review
  • ank_accept
  • ank_read
  • ank_close
  • ank_amend
  • ank_attest
  • ank_find
  • ank_status
  • ank_graph
  • ank_scope
  • ank_tui
  • ank_mcp
  • ank_watch
  • ank_edit
  • ank_check
  • ank_migrate
  • ank_archive
  • ank_config
  • ank_init
  • ank_skills
  • ank_update
  • ank_help
  • Com o nome ank_<verb>

    Um context puro colidiria com qualquer outro servidor carregado pelo cliente. O resumo vira a descrição, as flags viram o schema de entrada, e os argumentos posicionais chegam em arguments, um array de strings.

  • A resposta da CLI, com o código de saída

    Uma chamada devolve o documento que --json devolve, com exitCode ao lado. Uma recusa é a recusa da CLI, com dica e tudo, devolvida como resultado com isError. Um erro JSON-RPC quer dizer que a requisição estava errada; isError quer dizer que o corpus disse não.

  • Nenhum claim que a CLI não faria

    Todo claim vai para refs/ank/claims/ daquele repositório, sob o mesmo compare-and-swap. O servidor não segura nada em nome de um cliente e escreve como ank-mcp/<version>, a menos que ANK_AGENT nomeie uma identidade.

uma chamada que o corpus recusa
--> {"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"ank_show","arguments":{"arguments":["TASK-9999"]}}}

<-- {"jsonrpc":"2.0","id":2,"result":{"content":[{"type":"text","text":"error[2]: entity not found: TASK-9999\n  -> ank find TASK-9999"}],"isError":true,"exitCode":2,"stderr":"error[2]: entity not found: TASK-9999\n  -> ank find TASK-9999"}}

Vários repositórios, um servidor

Toda ferramenta aceita um argumento opcional corpus: o commit raiz que ank status --json imprime em "corpus", nunca um caminho. Declare cada repositório uma vez com ank config --user corpora.<root> <path> e a configuração do cliente não muda um caractere. Um servidor pode endereçar vários corpus; nunca mescla os claims deles.

ank_accept está lá como qualquer outro verbo, e continua recusando fora da branch padrão. Ratificar uma decisão continua sendo um ato humano.

MCP ou a CLI

Os dois chegam aos mesmos verbos e devolvem os mesmos documentos. Escolha pelo que seu cliente consegue fazer.

Seu agente tem shell

Use a CLI. npx skills add haksolot/ank dá ao agente as skills que ensinam o ciclo, e ele chama ank como qualquer outro comando.

Seu cliente não tem shell

Use ank mcp. O cliente vê os mesmos verbos como ferramentas, com as recusas e os códigos de saída escritos em cada descrição, então consegue ler o que uma chamada vai recusar antes de fazê-la.

Está construindo algo que exibe um corpus? Faça polling de ank_status e ank_find. ank_context e ank_show renovam um claim, e ank_check poda refs vencidas, ou seja, escreve.

Instalar o ank

Dois comandos. Linux, macOS e Windows, com git 2.34 ou mais recente.

npm install -g @haksolot/ank
npx skills add haksolot/ank