9. Extensions y MCP

Por: Artiko
goosemcpextensionsmodel-context-protocolsamplingelicitation

9. Extensions y MCP

Las extensions son las capacidades del agente. Un Goose sin extensions solo conversa. Con extensions puede leer archivos, correr comandos, llamar APIs, modificar bases de datos, y mucho más.

Hay dos tipos:

  • Built-in: vienen empaquetadas con Goose (filesystem, shell, fetch, memory).
  • MCP servers: externas al binario, conectadas vía Model Context Protocol.

Anatomía de una extension

flowchart LR
    G[Goose] -->|tool definition| M[Modelo]
    M -->|tool call| G
    G --> X[Extension]
    X -->|resultado| G

Cada extension declara herramientas con:

  • Nombre y descripción (para que el modelo decida cuándo usarla).
  • Schema de inputs (JSON Schema).
  • Schema de outputs.
  • Permisos requeridos (filesystem read/write, network, etc.).

Extensions built-in

developer

La más usada. Provee:

  • read_file(path)
  • write_file(path, content)
  • edit_file(path, old, new)
  • list_files(path, glob?)
  • shell(command)
  • git_operations
goose extension enable developer

fetch

HTTP requests:

  • fetch(url, method, body?, headers?)

Útil para integraciones con APIs externas, scraping, validar URLs.

memory

Persistencia local de notas:

  • remember(key, content)
  • recall(key)
  • list_memories()

Para que el agente “recuerde” cosas entre sesiones sin meterlas en persistent.md.

computer-use (experimental)

Control de la GUI del sistema:

  • take_screenshot()
  • click(x, y)
  • type(text)

Cuidado: requiere permisos OS y puede romper cosas si se descontrola.

automation

Tareas programadas:

  • schedule(cron, recipe)
  • list_scheduled()

MCP servers — el ecosistema externo

MCP (Model Context Protocol) es el estándar abierto para que herramientas externas se conecten a agentes. Goose es uno de los muchos clientes MCP.

flowchart LR
    G[Goose] <-->|MCP| F[Filesystem MCP]
    G <-->|MCP| GH[GitHub MCP]
    G <-->|MCP| PG[Postgres MCP]
    G <-->|MCP| S[Slack MCP]
    G <-->|MCP| Custom[Custom MCP\nde tu equipo]

Hay cientos de MCP servers públicos: GitHub, GitLab, Postgres, MySQL, Redis, Slack, Notion, Linear, Jira, Stripe, Shopify, Sentry, Datadog, etc.

Instalar un MCP server

# Por nombre (si está en el registry)
goose extension install github

# Por URL
goose extension install https://github.com/empresa/custom-mcp

# Manual via config
goose extension add my-postgres \
  --command "uvx mcp-server-postgres" \
  --env "POSTGRES_URL=postgres://..."

Configurar manualmente

~/.config/goose/config.yaml:

extensions:
  github:
    enabled: true
    type: stdio
    command: npx
    args: ["-y", "@modelcontextprotocol/server-github"]
    env:
      GITHUB_PERSONAL_ACCESS_TOKEN: ${GITHUB_TOKEN}

  postgres:
    enabled: true
    type: stdio
    command: uvx
    args: ["mcp-server-postgres"]
    env:
      POSTGRES_URL: ${PROD_DB_URL}

  remote-mcp:
    enabled: true
    type: sse
    url: https://mcp.empresa.com/sse
    auth:
      bearer_token_env: MCP_TOKEN

Tres tipos de transport:

  • stdio: server local, Goose lo lanza como subprocess.
  • sse: servidor remoto via HTTP con Server-Sent Events.
  • http: servidor remoto JSON-RPC sobre HTTP plano.

MCP Sampling

MCP Sampling convierte un MCP server en un agente propio: puede pedirle al cliente (Goose) que use el modelo para decidir algo.

Caso típico: un MCP server de Postgres que cuando le pedís “buscar usuarios sospechosos” no tiene una query hardcoded, sino que le pide al modelo que genere la query SQL apropiada para tu schema.

sequenceDiagram
    participant U as Usuario
    participant G as Goose
    participant M as Modelo
    participant S as MCP Server
    U->>G: "buscá usuarios sospechosos"
    G->>S: tool call: find_suspicious_users()
    S->>G: sampling request: "dame SQL para X schema"
    G->>M: prompt
    M-->>G: SELECT...
    G-->>S: SQL
    S->>S: ejecuta query
    S-->>G: resultados
    G-->>U: respuesta final

Esto hace que un MCP server pueda comportarse de forma adaptativa sin tener que conocer el modelo de antemano. Es una de las features más potentes del estándar.


MCP Elicitation

Mecanismo para que un MCP server le pida información estructurada al usuario durante una operación.

Ejemplo: un MCP de despliegue que en mitad de un deploy se da cuenta de que falta una variable de entorno, y en lugar de fallar, te pide:

🪿 [github-deploy MCP] Necesito un valor para SLACK_WEBHOOK_URL.
   Por favor pegalo:
> https://hooks.slack.com/services/...

El server pause su ejecución hasta que respondés. Útil para flujos largos donde no querés que falle por una pregunta puntual.

Configuración: en versiones recientes de Goose, está habilitado por default. En anteriores requiere flag explícito.


MCP Roots

Roots son los directorios que el cliente expone al servidor MCP.

Si Goose le dice al MCP server de filesystem “tu root es /home/user/proyecto”, el server no puede acceder a otros directorios aunque el modelo se lo pida. Sandbox de directorios automático.

extensions:
  filesystem:
    enabled: true
    roots:
      - /home/artiko/proyectos/mi-app
      - /tmp/scratch

Con esto, cualquier intento de leer /etc/passwd o ~/.ssh/id_rsa falla de plano.


MCP-UI y MCP Apps

MCP Apps son MCP servers que proveen UI (no solo herramientas), pensadas para Goose Desktop.

Ejemplos:

  • Un MCP de diseño que muestra un canvas para arrastrar componentes.
  • Un MCP de DB que muestra un query builder visual.
  • Un MCP de deploy que muestra un dashboard de status.
flowchart LR
    GD[Goose Desktop] -->|tool calls| MCP[MCP Server]
    MCP -->|UI definition\n(html/svg/json)| GD
    GD -->|render| User[Usuario]
    User -->|input| GD
    GD -->|user input| MCP

Para CLI users, el UI se reemplaza por equivalentes texto / ASCII (con limitaciones). Para Desktop, es una experiencia rica.


Custom Distributions

Si tu equipo necesita una versión interna de Goose con extensions pre-instaladas, podés armar una custom distribution:

# Estructura
my-goose-distro/
├── distribution.yaml
├── extensions/
   ├── my-internal-mcp/
   └── another-mcp/
└── persistent.md       # política empresarial inyectada en cada sesión

distribution.yaml:

name: empresa-goose
version: 2.1.0
base: goose-1.x.y
extensions:
  - my-internal-mcp
  - github
  - postgres
allowlist:
  enabled: true
  extensions: [my-internal-mcp, github, postgres]
default_provider: acp
default_model: empresa-llm-v3
goose distribution build my-goose-distro/
# Genera un instalador que tu IT puede deployar a developers internos

Esto permite distribuir Goose con la configuración corporativa baked-in, sin que cada developer tenga que setup todo manualmente.


Buscar y descubrir MCPs

goose extension search github         # busca en el registry
goose extension search --category db
goose extension show postgres         # detalles

Recursos externos donde encontrás servers MCP:

  • Registry oficial de MCP en modelcontextprotocol.io
  • awesome-mcp en GitHub
  • Goose marketplace

Construir tu propio MCP server

Si necesitás capabilities que no existen, escribís tu propio MCP server. SDKs oficiales:

  • TypeScript: @modelcontextprotocol/sdk
  • Python: mcp

Esqueleto mínimo TypeScript:

import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";

const server = new Server({ name: "mi-mcp", version: "1.0.0" }, { capabilities: { tools: {} } });

server.setRequestHandler("tools/list", async () => ({
  tools: [
    {
      name: "calcular_precio",
      description: "Calcula precio con descuentos aplicados",
      inputSchema: {
        type: "object",
        properties: {
          producto_id: { type: "string" },
          cantidad: { type: "number" },
        },
      },
    },
  ],
}));

server.setRequestHandler("tools/call", async (req) => {
  if (req.params.name === "calcular_precio") {
    const { producto_id, cantidad } = req.params.arguments;
    // tu lógica
    return { content: [{ type: "text", text: `precio: $42.50` }] };
  }
});

await server.connect(new StdioServerTransport());

Configurás en Goose y listo. Tu MCP funciona también con Claude Desktop, Cursor, Continue.dev y cualquier otro cliente MCP — esa portabilidad es el valor del estándar.


¿Qué viene?

Sabés extender Goose hasta donde te imagines. En el próximo capítulo cubrimos recipes: la forma en que Goose convierte tareas repetidas en flujos parametrizables, compartibles y ejecutables sin sesión interactiva.