ManualSlima MCP › Herramientas de edición estructurada (update_*)

Herramientas de edición estructurada (update_*)

Última actualización 9/09/2026 · 10 min de lectura

En una línea: cómo las herramientas update_* permiten que una IA externa modifique una escaleta, una cronología, un guion, un mapa de relaciones o un mapa del mundo sin perder por el camino las partes que nunca llegó a ver.

Qué resuelve

Un archivo de prosa se puede reescribir entero. La IA leyó todo el .md, así que puede devolverlo todo, y lo peor que puede pasar es que escriba mal y tengas que volver atrás desde el historial de versiones.

Con los archivos estructurados no existe esa red. Una escaleta .beats guarda actos, beats y las tarjetas de capítulo que el autor arrastró hasta ahí. Un .map guarda nodos, relaciones, cajas de grupo y la posición de cada nodo en el lienzo. Pedirle a una IA que devuelva el JSON completo es pedirle que devuelva también lo que nunca vio. Lo va a intentar, y el fallo es silencioso: el archivo sigue abriéndose, solo que con menos trabajo del autor dentro.

Por eso el servidor 4.0 cerró la escritura de archivo completo en estas cinco extensiones. write_file, edit_file y append_to_file se rechazan, y en su lugar hay una herramienta a nivel de campo por cada tipo.

Extensión Herramienta Operaciones
.beats escaleta update_beat_board add_act / update_act / remove_act / add_beat / update_beat / remove_beat / move_beat
.timeline cronología update_timeline add_entry / update_entry / remove_entry / set_config
.script guion update_script add_scene / update_scene_heading / remove_scene / add_element / update_element / remove_element
.map mapa de relaciones update_relationship_map add_node / update_node / move_node / remove_node / add_edge / update_edge / remove_edge / add_group / update_group / remove_group / set_meta
.geomap mapa del mundo update_world_map add_place / update_place / add_label / update_label / remove_element / add_river / add_border / paint_region / set_meta

No te aprendas esa tabla de memoria ni la trates como la fuente autorizada. get_capabilities devuelve lo que este servidor acepta ahora mismo: mira Guías y habilidades de escritura.

Reglas que valen para todas ellas

Lee el archivo primero. Cada id que envíes tiene que venir de esa lectura. Nunca lo reescribas de memoria y nunca te lo inventes. Un id desconocido se rechaza con la lista de los reales, así que el error cuesta una ida y vuelta, no los datos del autor.

Una operación por cambio. Cada operación acepta solo sus propios argumentos. Un campo que pertenece a otra operación se rechaza, no se ignora en silencio.

op_ref encadena dentro de un mismo lote. Etiqueta lo que crea una operación con op_ref: "A2" y una operación posterior del mismo lote podrá apuntar a ella con "@A2". Solo referencias hacia atrás, y solo dentro de ese lote: la siguiente llamada necesita el id real, que volvió en applied.

El lote es todo o nada. Si una operación falla no se escribe nada, así que nunca tienes que deducir hasta dónde llegó. Una sola llamada admite como máximo 200 operaciones; más que eso se rechaza pidiéndote que las dividas.

Un ejemplo completo

update_relationship_map({
  "book_token": "bk_...",
  "path": "Construcción del mundo/Mapa de relaciones.map",
  "intent": "Colocar a Wen Yun junto a Pei Zhao y marcarlos como colegas",
  "operations": [
    { "op": "add_node", "label": "Wen Yun", "op_ref": "N1",
      "position": { "near_id": "n-peizhao", "direction": "right" } },
    { "op": "add_edge", "source_id": "n-peizhao", "target_id": "@N1", "label": "colegas" }
  ]
})

intent no es un comentario. Se convierte en el nombre del commit, o sea, la línea que el autor va a leer en el historial de versiones dentro de tres semanas. Di qué hizo este lote. «Actualización por lotes» no es eso, y un párrafo demasiado largo se rechaza antes de escribir nada.

La respuesta trae tres cosas: los ids reales de lo que hayas creado, todo lo que ocurrió como efecto colateral (borrar un nodo borra también sus líneas) y el token del commit. Lo del medio hay que contárselo al autor: son cambios que va a ver en pantalla y que no pidió.

Aquí no hay panel de revisión

Dentro de la app, cuando el Coach de escritura IA cambia un archivo estructurado, el cambio aparece primero como una tarjeta punteada que el autor acepta u omite (mira Revisar cambios: revisa las ediciones de la IA).

Por MCP no existe ese paso. Un lote enviado desde una herramienta externa es un commit, y entra en el historial de versiones de inmediato. Así que di lo que vas a hacer antes de hacerlo y cuenta lo que hiciste después; no lo envíes para preguntar luego «¿así está bien?». Deshacer es el historial de versiones, igual que con un párrafo escrito a mano. Y en el historial nada marca un commit como venido de fuera: la fila muestra el mensaje, cuándo ocurrió y un recuento de palabras, y nada más. Tu línea de intent es el único rastro, que es justamente por lo que tiene que decir algo.

Crear un archivo estructurado

create_file sí funciona con estas cinco extensiones, pero el contenido que envías se ignora: el servidor escribe un esqueleto vacío y el nombre del archivo pasa a ser el nombre del documento que hay dentro. La respuesta dice con todas las letras que tu contenido fue reemplazado.

Son dos pasos, entonces: create_file para tener uno vacío y después lotes de update_* para llenarlo.

Quién puede hacer esto

Escribir estos cinco tipos —y borrarlos— pertenece a los planes de suscripción de Slima. Una cuenta Free recibe un 403 con el código SUBSCRIPTION_REQUIRED, y el mensaje deja claro que la lectura no está restringida: lee el archivo, describe con palabras el cambio que recomiendas y el autor podrá hacerlo en la app, o suscribirse y dejar que lo haga la IA.

Este rechazo no es el mismo que el otro. .character, .location, .json y .yaml devuelven AI_READONLY_FILE_TYPE, que ninguna mejora de plan desbloquea: esos tipos no tienen ninguna vía a nivel de campo. Los dos códigos están separados a propósito, porque el siguiente paso es completamente distinto.

Detalles propios de cada tipo

.map mapa de relaciones. La posición es contenido, no maquetación. update_node no mueve nada; mover es move_node, para que «la puse al lado de él» sea un cambio propio y revisable. Usa {near_id, direction} antes que calcular coordenadas a mano: los nodos existentes nunca se apartan y las coordenadas finales vuelven en la respuesta. Las cajas de grupo se calculan a partir de member_ids, así que jamás envíes x/y/ancho/alto.

.geomap mapa del mundo. Las coordenadas son celdas de rejilla, no píxeles: x de 0 a 519, y de 0 a 363. read_file devuelve el mapa con sus tres rejillas de terreno sustituidas por una nota; están codificadas para la máquina y no te hacen falta. paint_region trabaja en celdas. El terreno no tiene deshacer: se pinta encima. remove_element acepta el id de cualquier elemento (pl_ lugar, lb_ etiqueta, rv_ río, bd_ frontera). Un lugar se mueve con update_place, nunca borrándolo y volviéndolo a añadir.

.timeline cronología. Enganchar una entrada a un capítulo no se hace aquí; los campos de vínculo se rechazan con una explicación.

.beats escaleta. Quitar un acto no quita los beats que había dentro. Quedan sin asignar, y la respuesta te dice cuántos son.

.script guion. Un episodio por archivo. Los encabezados de escena (interior o exterior, lugar, momento del día) van por update_scene_heading; acción, personaje, diálogo, acotación, transición y plano van por add_element / update_element.

Relacionado

Pruébalo en Slima

Abre la app y hazlo con tu propio libro. Gratis para empezar, sin tarjeta de crédito.

Abrir Slima
¿Te resultó útil?