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:


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:


Extensions built-in

developer

La más usada. Provee:

goose extension enable developer

fetch

HTTP requests:

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

memory

Persistencia local de notas:

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

computer-use (experimental)

Control de la GUI del sistema:

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

automation

Tareas programadas:


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:


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:

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:


Construir tu propio MCP server

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

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.