El servidor MCP de ank

Cada verbo de la CLI como una herramienta, para un cliente sin shell. Una línea para añadirlo a Claude Code:

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

Qué es ank mcp

ank mcp es un verbo del único ejecutable que instala cada vía de instalación. No hay un segundo archivo que descargar: lo que la CLI despacha es lo que sirve el servidor, porque son el mismo binario.

Habla JSON-RPC sobre stdio y lo lanza el cliente. Así que no se arranca, se configura: un comando, sus argumentos y el repositorio en cuyo nombre habla.

Configurar un cliente

La entrada es el mismo JSON en los tres clientes. Solo cambia el archivo donde va.

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

Dónde va

Claude Code
.mcp.json en la raíz del repositorio, la forma que viaja con el tree y llega a todo el que lo clona. O la línea claude mcp add de arriba, que escribe la entrada por ti.
Claude Desktop
claude_desktop_config.json, en ~/Library/Application Support/Claude/ en macOS y en %APPDATA%\Claude\ en Windows.
Cursor
.cursor/mcp.json junto al repositorio, o ~/.cursor/mcp.json para todos los proyectos a la vez.

El comando es ank, y mcp su primer argumento

Hasta la 0.6.0, las releases instalaban un segundo ejecutable llamado ank-mcp. Ninguna vía lo instala ya, así que una configuración que todavía lo nombra recibe command not found. Es la única línea que hay que cambiar.

Escribe siempre --repo

Un cliente lanza el servidor en el directorio donde esté, y sin --repo el servidor toma ese directorio. El fallo no es un error: es un proceso que habla tranquilamente en nombre de un corpus que nadie quería, o de ninguno. Una ruta sin .ank/ se rechaza al arrancar, donde una persona lo ve.

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

Cada verbo, una herramienta

Las herramientas se generan a partir de la misma tabla que despacha el binario y que describe ank help --json. No es un subconjunto elegido a mano: las dos superficies no pueden discrepar sobre lo 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
  • Con nombre ank_<verb>

    Un context a secas chocaría con cualquier otro servidor que tenga cargado el cliente. El resumen pasa a ser la descripción, los flags el esquema de entrada, y los argumentos posicionales llegan en arguments, un array de strings.

  • La respuesta de la CLI, con su código de salida

    Una llamada devuelve el documento que devuelve --json, con exitCode al lado. Un rechazo es el rechazo de la CLI, pista incluida, devuelto como resultado con isError. Un error JSON-RPC significa que la petición estaba mal; isError significa que el corpus dijo que no.

  • Ningún claim que la CLI no haría

    Cada claim acaba en refs/ank/claims/ de ese repositorio, con el mismo compare-and-swap. El servidor no retiene nada en nombre de un cliente y escribe como ank-mcp/<version>, salvo que ANK_AGENT nombre una identidad.

una llamada que el corpus rechaza
--> {"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"}}

Varios repositorios, un servidor

Cada herramienta acepta un argumento opcional corpus: el commit raíz que ank status --json muestra bajo "corpus", nunca una ruta. Declara cada repositorio una vez con ank config --user corpora.<root> <path> y la configuración del cliente no cambia ni un carácter. Un servidor puede dirigirse a varios corpus; nunca fusiona sus claims.

ank_accept está ahí como cualquier otro verbo, y sigue negándose fuera de la rama por defecto. Ratificar una decisión sigue siendo un acto humano.

MCP o la CLI

Los dos llegan a los mismos verbos y devuelven los mismos documentos. Elige según lo que pueda hacer tu cliente.

Tu agente tiene shell

Usa la CLI. npx skills add haksolot/ank le da al agente las skills que le enseñan el ciclo, y llama a ank como a cualquier otro comando.

Tu cliente no tiene shell

Usa ank mcp. El cliente ve los mismos verbos como herramientas, con los rechazos y los códigos de salida escritos en cada descripción, así que puede leer qué rechazará una llamada antes de hacerla.

¿Construyes algo que muestra un corpus? Consulta ank_status y ank_find. ank_context y ank_show renuevan un claim, y ank_check poda refs obsoletas, así que escribe.

Instalar ank

Dos comandos. Linux, macOS y Windows, con git 2.34 o posterior.

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