Una herramienta flexible supera a cien dedicadas

cuando quería que un agente de LLM se comunicara con un sistema a principios de 2026 era instalar un servidor MCP para él.

GitHub. Jira. Flojo. Lineal. Postgres. Neo4j. Cada uno incluye un servidor que expone un menú ordenado de herramientas, create_issue, list_pull_requests, merge_pull_request, get_repository, search_code, etc., y usted le indica a su agente.

Es una gran experiencia de incorporación. Además, para un número sorprendente de cargas de trabajo reales, tiene la forma incorrecta.

La tesis es breve: el diseño de MCP generalmente envuelve cada servicio como un montón de herramientas dedicadas; una CLI le entrega al agente una herramienta realmente flexible. Con los modelos actuales, gana la herramienta flexible.

Comparación de enfoques MCP vs CLI.

Las dos formas piden al modelo que haga un trabajo diferente. Con un montón de herramientas dedicadas, el agente sólo tiene que elegir la correcta de un menú. Con una herramienta flexible, tiene que descubrir por sí mismo cómo unir las piezas. Esa segunda parte solía ser la difícil. Los modelos alucinaban banderas, perdían el hilo en tuberías largas, leían mal el texto de ayuda, por lo que envolver cada operación en una herramienta prefabricada era una defensa sensata. Eso ya no es cierto. Los modelos actuales leen una página de ayuda o SKILL.md cuando lo necesitan, conocen las CLI canónicas del entrenamiento, encadenan bash sin supervisión y vuelven a intentarlo cuando obtienen un indicador incorrecto. La parte difícil se volvió fácil, la parte fácil siempre fue fácil, y todas esas herramientas cuidadosamente empaquetadas en su mayoría simplemente inflan el contexto del modelo para nada ahora.

Por supuesto, no todo son rosas y sol. Entregarle al agente una terminal también le otorga un radio de explosión mucho mayor. La misma flexibilidad que le permite componer gh | jq | xargs en algo útil también permite que una inyección rápida lo convierta en algo mucho peor que una consulta Cypher hostil. Entonces, sí, hay una compensación y realmente hay que pensar en ello (zona de pruebas, lista de permitidos, usuario de sistema operativo separado, función de solo lectura en la base de datos, lo habitual).

Pero cuando puedes darle al agente una terminal de una manera razonablemente segura, el lado flexible aún sale ganando.

Donde brilla CLI

El mismo patrón de “envolver un servicio como un montón de herramientas dedicadas” aparece dondequiera que lo haga MCP. MCP de Postgres frente a psql. MCP de Kubernetes frente a kubectl. MCP del sistema de archivos frente a cat, ls, mv, grep pegados por tuberías. El mismo instinto siempre, la misma contraparte CLI siempre. Y también los mismos tres modos de falla, porque en realidad no se trata de ningún producto en particular.

En realidad, nada en la especificación MCP requiere este enfoque de acumular herramientas dedicadas. El protocolo pide herramientas mecanografiadas, nada más; no dice nada sobre cuán estrecha debe ser cada herramienta. Las implementaciones simplemente gravitan hacia muchas herramientas pequeñas y estrechas por razones históricas. Puede crear herramientas flexibles que tomen una única entrada expresiva y el agente le dé forma como quiera, y la mayoría de las veces probablemente debería hacerlo.

Para hacerlo concreto, veremos un ejemplo que compara el servidor MCP Neo4j con la CLI Neo4j.

Descargo de responsabilidad desde el principio: trabajo en Neo4j. La elección es simplemente conveniente, pero lo aprendido se aplica a la mayoría de las demás CLI.

El servidor Neo4j MCP es el servidor oficial que expone Neo4j a los agentes a través de MCP, y ofrece un puñado de herramientas dedicadas como lectura de consultas, escritura de consultas y obtención de esquema. neo4j.sh es la interfaz de línea de comandos oficial para Neo4j, un único binario que ejecuta en una terminal con perfiles de credenciales para cada base de datos con la que habla. Para mantener la comparación honesta, solo veremos el par de consulta de lectura y esquema en el lado de MCP con la invocación de consulta equivalente en neo4j.sh. Las mismas operaciones, la misma base de datos, el mismo Cypher pasando por el cable. Lo único que cambia es si el agente llega a ellos a través de un esquema de herramienta escrito o mediante una cadena entregada a un shell.

Consultas entre entornos

Ya vimos cómo un montón de herramientas dedicadas se comen la ventana contextual con descripciones, y que algunos servidores ahora envían herramientas diferidas para reducir ese costo hasta que el agente realmente las utilice. Pero hay un segundo multiplicador del que nadie habla: qué sucede cuando quieres hablar con más de una instancia del mismo servicio. Con MCP, el número de herramientas no solo crece con las funciones, sino que también crece con los entornos.

Conexión a múltiples bases de datos a través de MCP o CLI.

El agente quiere un recuento de nodos de desarrollo, preparación y producción. A través de MCP, usted establece un servidor neo4j-mcp por entorno, cada uno de los cuales lleva sus cuatro esquemas de herramientas al contexto del agente en cada turno. Tres bases de datos son doce esquemas en la ventana del modelo, los mismos cuatro esquemas tres veces, antes de que el agente haya hecho algo.

A través de la CLI, es un bucle for:

$ para c en dev staging prod-ro; hacer consulta neo4j-cli -c $c –format toon \ “MATCH (n) RETURN count(n) AS nodes” hecho

Un binario, tres perfiles de credenciales, cero costo de contexto por turno. Agregar un cuarto entorno es una adición más de dbms de credenciales, no un proceso de servidor MCP más. La misma forma se aplica a cualquier flujo de trabajo de “llegar a N cosas similares” que pueda desear: tomar instantáneas de la producción antes de una implementación riesgosa, diferenciar el esquema entre preparación y producción, ejecutar una verificación de estado en cada base de datos que el agente conoce.

Encadenamiento de consultas

Supongamos que el agente está investigando una cuenta de fraude conocida: a partir de una única semilla, encuentre cada cuenta con la que realizó transacciones y luego encuentre con qué otras cuentas esas contrapartes realizan transacciones con mayor frecuencia. Dos consultas a la misma base de datos, donde los parámetros de la segunda son el resultado de la primera.

Encadenamiento de consultas

A través de MCP, el modelo tiene que ser la tubería. Llama a read-cypher, el resultado regresa como una lista de, digamos, 80 ID de contraparte, esos 80 ID se encuentran ahora en el contexto del modelo, el modelo los formatea en el parámetro para la segunda llamada de read-cypher, y solo entonces puede consultar dos ejecuciones. La lista intermedia recorre la conversación palabra por palabra, y cada identificación adicional es otra fila de contexto por la que el agente paga, ya sea que la vuelva a leer o no.

A través de la CLI, la tubería es un literal |:

$ neo4j-cli consulta -c prod-ro –format json \ –param “seed=acct_19f3” \ “MATCH (:Cuenta {id: \$seed})-[:TRANSACTED]-(c:Cuenta) DONDE c.id <> \$seed RETURN recolectar(DISTINCT c.id) COMO contrapartes” \ | consulta neo4j-cli -c prod-ro –params-from-stdin \ “MATCH (a:Cuenta)-[:TRANSACTED]-(b:Cuenta) DONDE a.id EN \$contrapartes Y NO b.id EN \$contrapartes + [‘acct_19f3’]
REGRESAR b.id, contar(DISTINCT a) COMO bordes_into_cluster ORDENAR POR bordes_into_cluster DESC LÍMITE 20”

–params-from-stdin lee el resultado JSON de la consulta anterior y lo vincula como parámetro para la siguiente. La lista de contrapartes nunca ingresa al contexto del modelo, el costo del token del agente es el mismo ya sea que el grupo tenga 5 contrapartes o 500.

Aquí es donde el caparazón comienza a sentirse como una categoría de herramienta completamente diferente. El agente ya no selecciona de un menú de operaciones, sino que compone canalizaciones y los datos intermedios nunca tienen que salir a la superficie. Una consulta de dos pasos se convierte en |. Un despliegue se convierte en un bucle for. Una unión entre dos bases de datos se convierte en una consulta canalizada a otra con –params-from-stdin. Cada uno de ellos serían tres o cuatro viajes de ida y vuelta de MCP con cada resultado intermedio mostrado a través de la ventana de contexto, y en ese punto el agente ha gastado más tokens barajando filas que pensando en ellas.

Canalización a través de muchas CLI

Mismo problema, mayor escala. Digamos que el agente quiere materializar los problemas recientes de GitHub de un proyecto en Neo4j: un nodo :Issue por ticket, un nodo :User por autor, una relación :TAGGED por etiqueta. Los datos residen en una CLI (gh), quieren remodelarse (jq lo hace) y aterrizan en otra CLI (neo4j-cli). Tres herramientas diferentes en una línea. A través de MCP, accedería al servidor MCP de GitHub para obtener la lista de problemas, cada cuerpo de problema aterriza en el contexto del modelo, el modelo extrae los campos que desea y el cifrado de escritura se activa una vez por problema. Cientos de viajes de ida y vuelta a través del modelo, cada uno de los temas involucrados en la conversación a lo largo del camino.

A través de la CLI, tres programas en una tubería:

$ gh lista de problemas –repo neo4j/neo4j –limit 100 \ –json número,título,autor,etiquetas \ | jq-c’.[]’\ | mientras lee el problema; hacer consulta neo4j-cli –rw -c prod \ –param “data=$issue” \ “CON apoc.convert.fromJsonMap(\$data) COMO FUSIONAR (n:Problema {número: i.number}) SET n.title = i.title MERGE (u:Usuario {iniciar sesión: i.author.login}) FUSIONAR (u)-[:OPENED]->(n) FOREACH (etiqueta IN i.labels | MERGE (l:Etiqueta {nombre: etiqueta.nombre}) MERGE (n)-[:TAGGED]->(l))” hecho

gh elimina los problemas, jq remodela cada uno de ellos en una sola línea JSON, el bucle while entrega cada línea a neo4j-cli como un parámetro Cypher. El modelo escribe este guión una vez y luego se retira; los datos fluyen a través de bash, no a través del agente. Cien emisiones o diez mil, el coste simbólico del agente es el mismo.

La forma se generaliza mucho más allá de GitHub. Cambie gh por cualquier otra CLI que emita JSON (lista de problemas de Jira, lineal, curl contra un webhook, su propio comando de volcado interno), cambie el patrón Cypher por cualquier base de datos que esté creando y la canalización se realizará. Dos herramientas MCP no pueden conectarse entre sí; dos CLI pueden, y también diez.

El control de terminal es poderoso, y ese es el problema

El terminal no es una superficie fija, es la herramienta más flexible que puede entregarle a un agente porque se integra con todo lo demás en la caja.

Ese poder es también el truco. Una herramienta flexible mal utilizada causa daños flexibles. Un excelente acceso a la terminal conlleva una responsabilidad obvia: proteger el shell, incluir en la lista de permitidos los verbos que realmente desea, ejecutar el agente como un usuario de sistema operativo independiente, vincular credenciales a roles que físicamente no pueden hacer algo destructivo. Nada de esto es novedoso, es sólo higiene de administrador de sistemas aplicada a un LLM que escribe rápido. Y si no puede hacer nada de eso, un servidor MCP con una pequeña superficie fija sigue siendo la respuesta correcta; la garantía a nivel de protocolo de que el agente no puede cat ~/.ssh/id_rsa es algo real.

El punto más amplio es válido incluso si permanece completamente dentro de MCP. La razón por la que la terminal gana no es que bash sea especial, sino que bash es una herramienta con entrada muy flexible. Tuberías, variables, sustitución, bucles. Esa es la forma que vale la pena copiar. Lea el terminal como el caso límite de MCP y diseñe hacia él: menos herramientas, cada una de las cuales acepta entradas expresivas, el agente hace la composición en lugar de que usted anticipe cada combinación de antemano. La mayoría de los servidores MCP son una larga lista de puntos finales estrechos porque así es como la API subyacente ya estaba configurada, no porque el agente funcione mejor de esa manera. Los servidores que envejezcan bien serán los que eligieron a propósito una superficie más pequeña y expresiva.

Todas las imágenes de esta publicación de blog son creadas por el autor.