# MCP de Gandeo

> Documentación pública para agentes de IA que conectan con Gandeo mediante Model Context Protocol.

Endpoint: https://app.gandeo.com/api/mcp
Documentación web: https://app.gandeo.com/mcp
Versión del servidor: 1.1.0

## Conexión

1. El propietario o administrador crea una clave en Configuración > Developer Settings. Empieza con Solo lectura.
2. Guarda el token gandeo_mcp_* en el gestor de secretos del agente. Gandeo no vuelve a mostrarlo. Developer Settings también te ofrece un prompt listo para copiar y pegar en la IA.
3. Configura el servidor MCP con https://app.gandeo.com/api/mcp y el header Authorization: Bearer <TOKEN>.
4. Usa el transporte SSE: abre un GET autenticado, lee el evento endpoint y envía los mensajes JSON-RPC por POST a la URL que incluya sessionId.

### Configuración de un cliente MCP

```json
{
  "mcpServers": {
    "gandeo": {
      "url": "https://app.gandeo.com/api/mcp",
      "headers": {
        "Authorization": "Bearer <TOKEN>"
      }
    }
  }
}
```

### Transporte SSE y JSON-RPC

El GET autenticado mantiene abierta una conexión `text/event-stream` y devuelve un evento `endpoint` con una URL que contiene `sessionId`. Envía cada mensaje JSON-RPC por POST a esa URL con el mismo Bearer token. El POST responde `202 Accepted`; las respuestas MCP llegan por el stream SSE.

```bash
BASE_URL="https://app.gandeo.com/api/mcp"
TOKEN="gandeo_mcp_..."

# Mantén esta conexión abierta. La respuesta SSE incluye:
# event: endpoint
# data: /api/mcp?sessionId=<SESSION_ID>
curl -N \
  -H "Authorization: Bearer $TOKEN" \
  "$BASE_URL"
```

Ejemplo de inicialización:

```bash
curl -i -X POST "$BASE_URL?sessionId=<SESSION_ID>" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "initialize",
    "params": {
      "protocolVersion": "2025-06-18",
      "capabilities": {},
      "clientInfo": {"name": "mi-agente", "version": "1.0.0"}
    }
  }'
```

## Permisos

| Nivel | Qué permite | Herramientas principales |
| --- | --- | --- |
| Solo lectura (read) | Consultar explotaciones, animales, leche, derivados, documentos, economía, sanidad, reproducción, pesadas, pienso, parcelas, calendario, ayudas, notificaciones y auditoría. | describe_access, list_* y get_farm_snapshot |
| Lectura y escritura (write) | Todo lo anterior, además de crear y actualizar registros operativos y subir documentos. No puede borrar. | read + create_record, update_record, create_medication, upload_document |
| Administrador (admin) | Todo lo anterior, además de borrar registros permitidos. | write + delete_record |

## Herramientas

| Herramienta | Permiso | Entrada | Uso |
| --- | --- | --- | --- |
| `describe_access` | read | Sin argumentos. | Devuelve el nivel efectivo del token, la explotación permitida y las tablas disponibles. Llámala primero. |
| `list_farms` | read | Sin argumentos. | Devuelve la explotación asociada al token. |
| `list_animals` | read | farm_id, limit opcional. | Lista animales activos con sus datos principales. |
| `list_medications` | read | farm_id. | Lista el catálogo de medicamentos de la explotación. |
| `list_records` | read | farm_id, table, limit opcional. | Consulta una tabla permitida. La tabla y los campos válidos se descubren con describe_access y los esquemas MCP. |
| `get_farm_snapshot` | read | farm_id, limit_per_table opcional. | Devuelve una fotografía resumida de los módulos principales. Úsala para una visión general. |
| `create_record` | write | farm_id, table, data. | Crea un registro usando únicamente campos permitidos para esa tabla. |
| `update_record` | write | farm_id, table, id, data. | Actualiza un registro existente de la explotación y solo campos permitidos. |
| `delete_record` | admin | farm_id, table, id. | Borra un registro permitido. Requiere confirmación explícita del usuario. |
| `create_medication` | write | farm_id, name y campos sanitarios opcionales. | Añade un medicamento al catálogo. No prescribe ni confirma pautas veterinarias. |
| `lookup_cadastre` | read | province, municipality, cadastral_reference opcional, polygon opcional, parcel opcional. | Consulta datos oficiales de parcelas rústicas en el Catastro (superficie, paraje, referencia y coordenadas GPS). |
| `create_pasture` | write | farm_id, name y campos catastrales/operativos opcionales. | Crea una finca o parcela en la explotación con soporte de datos catastrales y estado de pastoreo. |
| `upload_document` | write | farm_id, file_name, mime_type, content_base64 y metadatos opcionales. | Conserva el archivo original en la explotación y crea su registro documental. |

## Tablas consultables

La respuesta de `describe_access` es la fuente de verdad. Estas son las familias actuales:

- **Explotación:** farms, animals, lots, contacts
- **Documentos:** documents, document_files, document_extractions
- **Economía:** transactions, transaction_animals
- **Sanidad:** medications, treatments
- **Leche:** dairy_tanks, dairy_lactations, milk_production_records, milk_samples, milk_deliveries, milk_settlements, milk_exclusion_periods, udder_health_events, dairy_forecast_snapshots, dairy_cuaderno_entries
- **Derivados lácteos:** dairy_products, dairy_batches, dairy_batch_milk_inputs, dairy_batch_ingredients, dairy_batch_outputs, dairy_inventory_movements
- **Reproducción:** heat_detections, breeding_events, pregnancy_checks, births, birth_offspring
- **Peso:** weight_records
- **Pienso:** feed_products, feed_stock_movements
- **Planificación y Pastoreo:** alerts, pastures, pasture_rotations, operational_units, operational_unit_pastures, pasture_sectors, grazing_occupations, field_activities, mowing_activities, custom_calendar_events
- **Sistema:** notifications, subsidy_farm_opportunity_matches, audit_events

## Flujo recomendado

1. **Descubre el permiso:** Llama a describe_access y conserva el farm_id devuelto. No pidas otra explotación.
2. **Lee antes de actuar:** Para preguntas generales usa get_farm_snapshot. Para detalle, list_records o la herramienta específica.
3. **Explica la fuente:** Cita la tabla, el registro y la fecha cuando estén disponibles. Si faltan datos, dilo claramente.
4. **Espera confirmación:** Antes de crear, actualizar o borrar, resume los cambios y pide confirmación explícita al usuario.
5. **Verifica el resultado:** Después de una mutación, vuelve a consultar el registro y comunica cualquier error sin ocultarlo.

## Reglas de seguridad y calidad

- No hay SQL libre. No intentes acceder a Supabase, tablas no listadas ni rutas internas.
- Cada token está ligado a una sola explotación mediante api_keys.farm_id. No se puede cambiar ese alcance enviando otro farm_id; para otra explotación hay que crear otra clave.
- El rol del miembro puede reducir el permiso guardado en la clave: viewer no tiene MCP, member queda limitado a lectura y owner/admin puede usar el nivel concedido.
- Las escrituras usan listas blancas de tablas y campos, y se auditan con acciones mcp.*.
- Las tablas de leche y derivados son de solo lectura por MCP. Sus mutadores complejos permanecen dedicados, validados y ligados a confirmación explícita en Gandeo.
- No inventes animales, importes, tratamientos, fechas ni documentos. Si una extracción es incierta, presenta una propuesta y pide revisión.
- No incluy nunca tokens gandeo_mcp_* en respuestas, logs, repositorios, prompts persistentes o documentación.
- Usa Solo lectura por defecto. Eleva permisos solo cuando el caso de uso lo necesite y el usuario lo haya autorizado.

## Diagnóstico

| Síntoma | Solución |
| --- | --- |
| 401 Unauthorized | Comprueba que envías Authorization: Bearer <TOKEN>, que el token no está revocado y que el usuario sigue siendo miembro de la explotación. |
| 400 Missing sessionId | Primero abre el GET SSE y utiliza exactamente la ruta recibida en el evento endpoint. |
| 404 Session not found | La conexión SSE se cerró o la petición POST llegó a otra instancia. Abre una sesión nueva y mantén vivo el GET. |
| Error de permisos | Llama a describe_access. El farm_id debe coincidir con el permitido y la operación debe estar cubierta por read, write o admin. |

Para generar o revocar claves, usa Configuración > Developer Settings:
https://app.gandeo.com/mcp/es/dashboard/settings/developer

