# Herramientas

Las cuatro herramientas del servidor MCP de plnnrly, qué acepta y qué devuelve cada una, y los límites que se aplican.

El servidor MCP no tiene una herramienta por función. Con tres herramientas generales, un cliente de IA llega a todas las operaciones de la [API REST (en inglés)](https://developers.plnnrly.com/en/docs/api/v2/) salvo la subida de archivos, siempre en tu nombre y con tus permisos. Una cuarta herramienta devuelve tu propio perfil. Cuando la API incorpora una función nueva, los clientes pueden usarla de inmediato.

| Herramienta             | Título que muestran los clientes | Qué hace                                   |
| ----------------------- | -------------------------------- | ------------------------------------------ |
| `search_api`            | Search the API                   | Busca operaciones de la API y las describe |
| `api_read`              | Read from the API                | Envía un `GET` a una operación de la API   |
| `api_write`             | Write to the API                 | Envía un `POST`, `PATCH` o `DELETE`        |
| `get-current-user-tool` | Get current user                 | Devuelve tu perfil                         |

Tres herramientas solo leen. **Write to the API** está marcada como herramienta que puede cambiar datos, así que, por defecto, los clientes te piden que la apruebes. La mayoría de los clientes te dejan permitirla para una conversación o de forma permanente. [Permisos y seguridad](https://developers.plnnrly.com/es/docs/mcp/permissions-and-safety/) explica qué puede hacer un cliente.

## Cómo usa un cliente las herramientas

Cada cliente también recibe del servidor un breve conjunto de instrucciones. Describen tres pasos: encontrar la operación con `search_api`, leer lo que acepta y después llamarla con `api_read` o `api_write`. También le indican al cliente que:

- las rutas de los elementos de trabajo aceptan claves como `ACM-12`
- los filtros de usuario aceptan `me`
- eliminar necesita `confirm: true`, que solo se envía después de que hayas dado tu conformidad, y solo funciona si tu organización lo permite
- el texto se añade a un documento de Drive con `mode: append`, porque sin él se sustituye el documento entero

## search_api

Busca operaciones de la API y las describe. Solo devuelve la documentación de la propia API, nunca datos de tu organización.

| Entrada        | Tipo   | Obligatoria | Descripción                                                         |
| -------------- | ------ | ----------- | ------------------------------------------------------------------- |
| `query`        | string | no          | Palabras clave, como `link work items` o `log time`.                |
| `operation_id` | string | no          | Un `id` de un resultado de búsqueda, como `work-items.links.store`. |

- Con `query`, devuelve como máximo 12 coincidencias en forma de `{id, method, path, summary}`, más un `hint` con el siguiente paso.
- Con `operation_id`, describe esa operación: su descripción, el permiso que necesita, los parámetros de ruta, los parámetros de consulta, los filtros, las ordenaciones, las relaciones que se pueden incluir (`include`), los campos del cuerpo, la función a la que pertenece y uno o dos ejemplos. El id funciona con o sin el prefijo `api.v2.`.
- Sin ninguna de las dos entradas, enumera todos los ids de operación, agrupados por área.

Se omiten las operaciones que tu organización no puede usar: las de las áreas que tu organización no usa, las eliminaciones mientras **Permitir acciones destructivas** está desactivado y la subida de archivos.

## api_read

Envía un `GET` a cualquier operación de la API.

| Entrada | Tipo   | Obligatoria | Descripción                                                                                               |
| ------- | ------ | ----------- | --------------------------------------------------------------------------------------------------------- |
| `path`  | string | sí          | La ruta bajo `/api/v2`, con sus marcadores rellenados, como `work-items/ACM-12/comments`.                 |
| `query` | object | no          | Parámetros de consulta, como `{"filter": {"assignee_id": "me", "resolved": false}, "include": "labels"}`. |

### Rutas y consulta

- Una ruta vacía enumera los recursos que ofrece la API.
- La ruta puede empezar por `/api/v2`; el prefijo se ignora.
- La ruta completa tiene como máximo 256 caracteres. Sus segmentos solo usan letras, dígitos, `-` y `_`, y todos los marcadores deben estar rellenados.
- Las rutas de los elementos de trabajo aceptan claves, como `work-items/ACM-12`. Los filtros de usuario aceptan `me`.
- Los objetos de consulta se anidan como máximo tres niveles, como `filter[due_date][gte]`, con un máximo de 60 parámetros en total.
- Los valores nulos se omiten. Las listas se convierten en valores separados por comas.

### Listas y paginación

Las listas llegan en páginas de 10 en la vista resumida, salvo que la llamada pida otra cosa. Para obtener la página siguiente, pasa como `cursor` el `meta.page.next_cursor` de la respuesta anterior. Cuando `next_cursor` es `null`, no hay más páginas.

Algunas listas también aceptan un número de página. Su `meta.page` siempre tiene `current_page` y `last_page`, que son `null` salvo que la llamada envíe `page`. Una llamada que envía `page` siempre recibe `next_cursor: null`. La última página es aquella en la que `current_page` llega a `last_page`.

## api_write

Envía un `POST`, `PATCH` o `DELETE` a cualquier operación de la API.

| Entrada   | Tipo    | Obligatoria | Descripción                                                                                       |
| --------- | ------- | ----------- | ------------------------------------------------------------------------------------------------- |
| `method`  | string  | sí          | `POST`, `PATCH` o `DELETE`.                                                                       |
| `path`    | string  | sí          | La ruta bajo `/api/v2`, como `work-items/ACM-12/links`.                                           |
| `query`   | object  | no          | Parámetros de consulta, como `{"view": "detail"}`.                                                |
| `body`    | object  | no          | El cuerpo JSON, como `{"link_type": "blocks", "target_work_item_id": 42}`.                        |
| `confirm` | boolean | no          | `true` para una eliminación o una sobrescritura, y solo después de que hayas dado tu conformidad. |

Las reglas de ruta y consulta de `api_read` también se aplican aquí. El cuerpo se comprueba exactamente igual que en la API REST: un campo que la operación no acepta se rechaza por su nombre, nunca se ignora.

Eliminar necesita dos cosas: **Permitir acciones destructivas** debe estar activado para tu organización, y la llamada debe llevar `confirm: true`. Si falta cualquiera de las dos, no se elimina nada. [Qué cuenta como eliminar](https://developers.plnnrly.com/es/docs/mcp/permissions-and-safety/#destructive) enumera las operaciones afectadas. En `DELETE /projects/{project}`, la consulta `{"force": true}` elimina el proyecto de forma permanente, en lugar de hacer una eliminación que se puede deshacer.

Sustituir el texto completo de un documento de Drive también necesita `confirm: true`, porque descarta el formato y todo lo que otros hayan escrito desde que el cliente lo leyó. Añadir texto con `{"mode": "append"}` en el cuerpo no necesita confirmación.

`api_write` rechaza estas llamadas antes de que se ejecute nada:

| Rechazo                                                                      | Tipo de problema      |
| ---------------------------------------------------------------------------- | --------------------- |
| Una eliminación mientras **Permitir acciones destructivas** está desactivado | `forbidden-by-policy` |
| Una eliminación o sobrescritura sin `confirm: true`                          | `validation-failed`   |
| Una subida de archivo                                                        | `endpoint-not-found`  |
| Un método que la operación no acepta                                         | `method-not-allowed`  |

Ninguno de los dos primeros lee el registro antes de rechazar la llamada, así que un rechazo nunca revela si el registro existe.

Las escrituras mediante MCP no están protegidas contra duplicados. La cabecera `Idempotency-Key` ni se necesita ni se usa, así que un cliente que no sabe con seguridad si una escritura se completó debe leer antes de volver a intentarlo.

Si el inicio de sesión de una aplicación también pidió permisos de la API REST, mediante MCP queda limitada igualmente a esos permisos. Los permisos de un inicio de sesión nunca incluyen eliminar, así que esa aplicación no puede eliminar mediante MCP.

## get-current-user-tool

Devuelve tu propio perfil. No recibe ninguna entrada.

```json
{
  "id": 34,
  "name": "Jamie Doe",
  "email": "jamie@acme.example",
  "email_verified_at": "2026-02-03T09:15:00+00:00",
  "timezone": "Europe/Amsterdam",
  "locale": "en",
  "job_title": "Project manager",
  "date_employed": "2025-09-01",
  "roles": ["Project manager"],
  "created_at": "2025-08-28T14:02:11+00:00"
}
```

Las marcas de tiempo incluyen la diferencia con la hora UTC. `date_employed` es una fecha (`YYYY-MM-DD`). Los campos sin valor son `null`.

## Respuestas

Una respuesta correcta es el propio cuerpo de respuesta de la API, con dos cambios:

- Primero va una clave `status`, con el estado HTTP con el que respondió la API, como `200` o `201`.
- Se quitan todos los mapas `links`. Un cliente continúa una lista con `meta.page.next_cursor` y llama a otros registros por su ruta.

Una eliminación responde sin cuerpo, así que la herramienta devuelve `{"status": 204}`.

Una respuesta puede tener unos 30.000 caracteres. El límite cuenta bytes, así que en un texto con tildes o emojis caben algunos menos. Una respuesta más larga se acorta, pero nunca en silencio: `meta.mcp_truncated` indica qué se ha cortado. Cuando se omiten filas de una lista, `next_cursor` se vacía, porque al seguirlo esas filas se saltarían. El `hint` explica cómo seguir paginando sin huecos. Este es el objeto `meta` de una lista acortada:

```json
{
  "page": {
    "per_page": 10,
    "next_cursor": null,
    "prev_cursor": null,
    "total": null
  },
  "mcp_truncated": {
    "reason": "response_budget",
    "returned": 6,
    "omitted": 4,
    "hint": "Only the first 6 of 10 rows fit. Repeat this request with per_page=6 (and the same cursor, if any) to page through without gaps."
  }
}
```

Cuando el problema es un único texto largo, `mcp_truncated` enumera en su lugar los campos acortados, cada uno con su `pointer`, los caracteres que se han conservado (`kept`) y la longitud original (`length`).

## Errores

Una llamada rechazada vuelve como error de herramienta con el mismo [documento de error (en inglés)](https://developers.plnnrly.com/en/docs/api/v2/guides/errors/) que devuelve la API REST, con el mismo estado y el mismo tipo. Pedir algo que no tienes permiso para ver devuelve `404`, igual que mediante HTTP.

```json
{
  "type": "https://developers.plnnrly.com/api/v2/problems/forbidden-by-policy",
  "title": "Forbidden by policy",
  "status": 403,
  "detail": "This organisation does not allow AI clients to delete data. An administrator can turn on Allow destructive actions under Settings › Administration › MCP & API.",
  "instance": "/api/v2/work-items/ACM-12",
  "request_id": "01M4WVYY50K7T2B9QH3D6N8RXP"
}
```

Una ruta o una consulta que las herramientas no pueden usar responde [malformed-request](https://developers.plnnrly.com/en/docs/api/v2/guides/errors/#malformed-request). Su `errors[].code` es `invalid` (una ruta o un valor no permitidos), `too_many` (más de 60 parámetros de consulta) o `too_deep` (anidado más de tres niveles).

## Límites

- Cada usuario puede enviar 60 peticiones MCP por minuto. Cuenta cada petición que el cliente envía al servidor, incluidas las que establecen la conexión y enumeran las herramientas, no solo las llamadas a herramientas. Un cliente que supera el límite recibe `429`.
- Los límites de peticiones de la propia API REST y sus unidades de coste no se aplican a las llamadas mediante MCP.
- Una respuesta tiene unos 30.000 caracteres como máximo.
- El cliente renueva su inicio de sesión cada hora. Un cliente que no se usa durante 30 días tiene que volver a iniciar sesión.

[Límites de un vistazo (en inglés)](https://developers.plnnrly.com/en/docs/api/v2/guides/limits/) enumera todos los límites de la API REST.

## Lo que MCP no puede hacer

- **Subir archivos.** Añadir un adjunto o un archivo de Drive necesita una subida de bytes que los clientes MCP no pueden hacer. Usa la API REST con un token de API; consulta [Archivos: subida y descarga (en inglés)](https://developers.plnnrly.com/en/docs/api/v2/guides/uploads/).
- **Eliminar mientras el interruptor está desactivado.** Las eliminaciones solo funcionan mientras tu organización permite acciones destructivas.

## Páginas relacionadas

- [Qué puedes pedir](https://developers.plnnrly.com/es/docs/mcp/examples/)
- [Permisos y seguridad](https://developers.plnnrly.com/es/docs/mcp/permissions-and-safety/)
- [Solución de problemas](https://developers.plnnrly.com/es/docs/mcp/troubleshooting/)
- [Errores y reintentos (en inglés)](https://developers.plnnrly.com/en/docs/api/v2/guides/errors/)
