Skip to main content
Glama

🗞️ bome-navaja

Servidor MCP para el Boletín Oficial de la Ciudad Autónoma de Melilla (BOME)

Python MCP Licencia

Pregunta por el BOME en lenguaje natural: lista boletines, lee artículos y PDF completos, busca en vivo con la misma lógica que el sitio, consulta al instante un índice local de sumarios y llega hasta 1985 con el portal antiguo de melilla.es.


📑 Índice


Related MCP server: MCP-BOE

🧭 Qué es

bome-navaja es un programa local que tu cliente de IA (Claude Desktop, Claude Code…) lanza en tu máquina y con el que habla por el protocolo MCP. Le da al modelo acceso a bomemelilla.es: el calendario de boletines, el árbol de artículos de cada boletín, el texto completo de artículos y boletines, los PDF, el buscador del sitio y un índice local de sumarios para búsquedas instantáneas.

Cobertura (la de bomemelilla.es):

Periodo

Qué hay

Desde el 3 de enero de 2014

Los boletines ordinarios (BOME-B) y extraordinarios (BOME-BX), en el calendario y con su árbol de artículos (antes de 2018 faltan boletines)

Desde finales de 2016

Sumario de cada artículo, texto HTML completo y PDF

2014–2016

Los artículos no tienen sumario ni texto, y los PDF del boletín y de los artículos no se pueden descargar (el sitio responde 404 aunque muestre el botón). En bomemelilla.es solo se puede buscar dentro del contenido con buscar_bomes y ambito="contenido"

Para lo anterior a 2018, y para todo lo anterior a 2014, está el portal antiguo de melilla.es: boletines del 3 de enero de 1985 al 12 de marzo de 2021, con sumarios de artículos desde ~1991 y el PDF de cada página. Sus sumarios de 1991–2017 también se pueden guardar en el índice local.

bome-navaja solo lee datos públicos: no inicia sesión, no usa credenciales y no envía nada al sitio más allá de las consultas.


🧰 Herramientas

Todas devuelven un objeto con ok. Si algo falla devuelven ok: false, un error en castellano y un error_code estable (no_encontrado, cve_invalido, busqueda_invalida, lectura_invalida, argumento_invalido, error_http, sitio_bloqueando, pausa_preventiva, indice_no_disponible, y para el portal antiguo url_pdf_invalida y boletin_ambiguo…). Los mensajes de error nombran el sitio que falló (bomemelilla.es o melilla.es); nunca rompen la conversación con una excepción.

Grupo

Herramienta

Para qué sirve

Navegar

listar_bomes

Boletines publicados entre dos fechas (por defecto, los últimos 30 días; como mucho 500, del más reciente al más antiguo), cada uno con su origen; antes del 13 de marzo de 2021 añade los que solo tiene el portal antiguo

ver_bome

Un boletín con su árbol departamento → consejería → organismo → artículos; con recuperar_ocultos busca los artículos que la página omite

ver_sumario

La vista web del sumario, con la primera página de cada artículo (algunos sumarios son texto libre y dan 0 entradas: usa ver_bome)

resolver_cve

URL canónica de cualquier CVE (boletín, artículo, sumario o página). El resolutor del sitio confunde los artículos y páginas de extraordinarios (BOME-AX, BOME-PX) con los ordinarios: para BOME-AX el boletín se busca aparte, y para BOME-PX se devuelve la URL de su PDF

listar_consejerias

Consejerías de un departamento con su id, para filtrar búsquedas

listar_organismos

Organismos de una consejería con su id, para filtrar búsquedas

Leer y descargar

leer_articulo

Texto completo de un artículo, paginado

leer_boletin

Texto completo de un boletín entero (su PDF) con sus metadatos, paginado

leer_pdf

Texto del PDF de cualquier CVE, o de un PDF del portal antiguo con url, paginado

descargar_pdf

Guarda el PDF de un CVE (o de una url del portal antiguo) en la caché local y devuelve su ruta

Buscar en vivo

buscar_bomes

El buscador avanzado del sitio: devuelve boletines, 10 por página

buscar_articulos

Devuelve artículos: busca boletines, abre cada uno y se queda con los artículos cuyo sumario coincide

Índice local

buscar_en_indice

Búsqueda instantánea de artículos en el índice local de sumarios (bomemelilla.es y, una vez indexado, el portal antiguo), cada uno con su origen

estado_indice

Qué hay indexado de cada origen y cómo va la sincronización

sincronizar_indice

Arranca en segundo plano la sincronización del índice: de bomemelilla.es o, con origen="melilla.es", del portal antiguo

cancelar_sincronizacion

Pide parar la sincronización en curso, sea del origen que sea

Portal antiguo

buscar_bome_antiguo

Búsqueda literal de artículos en melilla.es (1985–2021), con sumario y PDF de cada página

ver_bome_antiguo

Un boletín del portal antiguo (por CVE o dboid): PDF entero y artículos con sus páginas

Servidor

estado_servidor

Versión, rutas de datos, SQLite disponible, guardias de los dos sitios y configuración, sin tocar la red

Los CVE tienen la forma BOME-L-AAAA-N: BOME-B-2026-6416 (boletín), BOME-BX-2026-41 (extraordinario), BOME-A-2026-1051 (artículo), BOME-S-2026-6416 (sumario), BOME-P-2026-4784 (página), BOME-PX-2021-362 (página de un extraordinario). Se aceptan en minúsculas y con espacios.


🔍 Cómo busca el sitio (y por qué importa)

Todo lo que sigue está medido contra el sitio real, no deducido de su interfaz. Condiciona cómo hay que redactar las búsquedas.

Regla

Consecuencia

Coincidencia literal por subcadena, sin distinguir tildes ni mayúsculas (la ñ cuenta como n)

"nombra" encuentra «nombramiento»; "cese" encuentra «cese», «ceses» y también «procese»

Sin sinónimos ni variantes

Busca "cese", no "destitución": esta última da 0 resultados porque el BOME no la usa. El orden de las palabras importa

El sitio ignora el texto si no recibe fecha de inicio (from)

El servidor la envía siempre (por defecto, desde el 2014-01-01 hasta hoy)

Los términos unidos con Y y los de «no contiene» se evalúan dentro de un mismo artículo

"personal eventual" Y "hacienda" no encuentra boletines donde esas palabras están en artículos distintos

El sitio ignora el O entre términos (lo trata como Y)

buscar_bomes rechaza el O; úsalo con buscar_articulos o buscar_en_indice, que lo aplican ellas mismas

Los criterios numéricos son exactos

Boletín 6416, artículo 1051, página 4784 o año 2025; 641 no encuentra el 6416

El buscador devuelve boletines, no artículos

buscar_articulos abre cada boletín para quedarse con los artículos que coinciden

La página de un boletín a veces omite artículos

buscar_articulos (y el índice) detectan los huecos de numeración y leen esos artículos de su propia página

Ejemplo: «nombramientos y ceses de personal eventual»

«Personal eventual» y «cese» deben estar en el mismo artículo; para incluir también los nombramientos hace falta un O, así que la herramienta es buscar_articulos (o buscar_en_indice si el índice ya está sincronizado). Los términos forman grupos Y separados por cada "operador": "o":

{
  "texto": "personal eventual",
  "terminos": [
    {"texto": "cese"},
    {"texto": "personal eventual", "operador": "o"},
    {"texto": "nombramiento"}
  ],
  "max_bomes": 50
}

Se lee así: (personal eventual Y cese) O (personal eventual Y nombramiento). El servidor lanza una búsqueda en el sitio por cada grupo, junta los boletines sin repetir, del más reciente al más antiguo, y devuelve cada artículo con su CVE, sumario, departamento, consejería, organismo, url y pdf_url.

Solo para los ceses, sin el O, basta con:

{"texto": "personal eventual", "terminos": [{"texto": "cese"}]}

Con esta última consulta, el sitio devolvió 12 boletines el 23 de septiembre de 2026.

TIP

buscar_articulos es lenta a propósito: una petición por boletín, con una pausa de cortesía. Está acotada por max_bomes (por defecto 20, máximo 100) y max_articulos (por defecto 100, máximo 500). Mira truncado y total_bomes antes de concluir que no hay más. Con O, total_bomes suma los resultados de cada grupo y puede contar un boletín dos veces: total_bomes_exacto es false en ese caso. Los boletines que el sitio encontró pero donde ningún sumario coincide (por ejemplo, los de 2014–2016, que no tienen sumarios) salen en bomes_sin_coincidencia.

Para buscar dentro del texto de las páginas (la única vía para 2014–2016), usa buscar_bomes con ambito="contenido"; devuelve boletines, no artículos.


📇 Índice local de sumarios

Un fichero SQLite en tu máquina con los sumarios de todos los artículos, indexado con FTS5 y el tokenizador trigram. Responde al instante y admite Y, O y «no contiene» dentro del mismo artículo, igual que buscar_articulos, pero sin tocar el sitio.

Guarda dos orígenes: bomemelilla.es (desde 2018 por defecto) y, si lo indexas, el portal antiguo de melilla.es (1991–2017 por defecto). Cada artículo de buscar_en_indice trae su origen ("bomemelilla.es" o "melilla.es"); en los del portal antiguo, url es la ficha del boletín en melilla.es y pdf_url el PDF de la página del artículo (se lee con leer_pdf y url).

coincidencia: fragmento o palabra

coincidencia

Regla

"cese" encuentra

"ano" encuentra

"fragmento" (por defecto)

Subcadena, igual que el sitio

cese, ceses, procese

año, humanos

"palabra"

Cada frase debe empezar una palabra (puede acabar a mitad de palabra)

cese, ceses

año

En los dos modos se ignoran tildes y mayúsculas, y un * final se acepta pero no cambia nada. Los términos de menos de 3 caracteres (p. ej. "de") no caben en un índice de trigramas: se resuelven recorriendo los sumarios, y funcionan igual. Otros parámetros: desde/hasta, extraordinario, consejeria (parte del nombre, sin tildes), orden ("fecha" o "relevancia", esta última aproximada), limite (máximo 200) y desplazamiento; siguiente da el desplazamiento de la página siguiente.

Sincronizar

  • Solo se sincroniza cuando el modelo llama a sincronizar_indice. El servidor nunca recorre el sitio por su cuenta, ni al arrancar.

  • La herramienta vuelve al instante; la sincronización sigue en segundo plano, del boletín más reciente al más antiguo.

  • Por defecto cubre desde el 1 de enero de 2018 hasta hoy. Antes de 2018 bomemelilla.es está incompleto e inestable (faltan boletines, sus páginas rotas responden HTTP 500 y de ahí vienen los bloqueos del cortafuegos) y casi no hay sumarios que buscar; esos boletines se consultan mejor en el portal antiguo de melilla.es. Puedes pedir un desde anterior, pero no es recomendable.

  • Va despacio a propósito (por defecto, ~2–3 s entre peticiones) y cada ejecución indexa como mucho 250 boletines (los más recientes; parámetro max_boletines), unos 15–20 minutos (más si el sitio responde con errores; ver abajo). El rango por defecto (~1.100 boletines desde 2018) necesita varias ejecuciones: si el estado final trae pendientes_tras_limite mayor que 0, vuelve a sincronizar más tarde. Espaciar las ejecuciones es más amable con el sitio. El índice completo ocupa del orden de 40–50 MB.

  • Es reanudable: cada boletín se guarda en cuanto se procesa. Si se corta, la siguiente llamada continúa donde quedó. Por defecto también reindexa los boletines de los últimos 7 días (reindexar_recientes_dias) y reintenta los que fallaron (reintentar_errores), salvo los roto.

  • Sigue el progreso con estado_indice (hechos, total_planificado, eta_segundos, rotos). Mientras tanto buscar_en_indice funciona, pero avisa de que los resultados son parciales.

  • cancelar_sincronizacion para tras el boletín en curso (o al instante si está en una pausa); lo ya indexado se conserva.

  • Cuida el cortafuegos del sitio, que bloquea la IP tras unas 5 respuestas de error (detalle en Seguridad y cortesía). Estas cifras, como el ritmo y el límite de arriba, son los valores por defecto: puedes cambiarlas en los ajustes de ritmo y protección:

    • No pasa de 3 respuestas de error cada 10 minutos: si llega al límite, hace una pausa preventiva (la indica mensaje), así que puede ir más lenta.

    • Tras una página de boletín rota (HTTP 500) hace una pausa de 30–60 s.

    • Un boletín cuya página respondió 500 dos veces queda como roto: las sincronizaciones normales lo saltan y estado_indice lo cuenta aparte, no como pendiente. reintentar_rotos: true los vuelve a pedir, pero cada uno cuesta un 500 que el cortafuegos cuenta: úsalo solo para comprobar si el sitio los arregló.

    • Si el sitio bloquea igualmente (403, 429 o 503, o dos peticiones seguidas sin respuesta), termina en estado bloqueado y bome-navaja no vuelve a pedirle nada durante 75 minutos (o más, si el sitio lo pide con Retry-After); reintentar_tras_segundos dice cuánto falta. Relánzala pasado ese tiempo: continúa donde quedó.

  • Si tienes dos clientes abiertos con bome-navaja (por ejemplo, Claude Desktop y Claude Code), solo uno sincroniza: el otro recibe en_curso_en_otro_proceso con el origen que ocupa el turno. Hay un solo turno por índice, sea cual sea el origen: mientras sincroniza bomemelilla.es no se puede sincronizar el portal antiguo, y al revés. El turno se considera abandonado si su dueño deja de dar señales durante 3 minutos.

Cada respuesta de buscar_en_indice trae un bloque cobertura (rango de fechas indexado, boletines indexados y pendientes, última sincronización, si hay una en curso, y lo indexado de cada origen en por_origen). Los pendientes cuentan solo desde 2018; los boletines anteriores que un índice de una versión previa tenga en su calendario sin indexar salen aparte en pendientes_anteriores_2018 (también en estado_indice). Si el índice está vacío, devuelve 0 resultados y un aviso que sugiere sincronizar o usar buscar_articulos mientras tanto.

Indexar el portal antiguo (melilla.es)

sincronizar_indice con origen="melilla.es" guarda en el mismo índice los sumarios de artículos del portal antiguo, para buscar con Y, O y «no contiene» en 1991–2017 y en varios años a la vez, cosa que la búsqueda del portal (literal, de una sola frase y sin paginar) no permite.

{"origen": "melilla.es"}
  • Qué indexa: los sumarios de la ficha de cada boletín (ficha_bome.jsp), con una petición por boletín y nunca los PDF. Por defecto, los boletines del 1 de enero de 1991 al 31 de diciembre de 2017: antes de 1991 las fichas no traen artículos (solo el PDF del boletín entero) y desde 2018 está bomemelilla.es. Admite otro desde/hasta.

  • El mismo ritmo y el mismo límite que la de bomemelilla.es: por defecto, 2 s más hasta 1 s aleatorio entre peticiones y como mucho 250 boletines por ejecución (max_boletines), unos 15–20 minutos. El rango por defecto tiene unos 2.000–2.500 boletines, así que hacen falta unas 8–10 ejecuciones, mejor espaciadas; pendientes_tras_limite dice cuántos quedan. Los ajustes de ritmo y protección (BOME_NAVAJA_SYNC_DELAY, BOME_NAVAJA_SYNC_MAX_BOLETINES y el resto) son los mismos para los dos orígenes.

  • Es reanudable y no repite trabajo: se salta los boletines ya indexados con sumarios (de cualquier origen) y los que el portal ya dio sin artículos. Reintenta los fallidos (reintentar_errores) y los roto solo con reintentar_rotos. reindexar_recientes_dias no se aplica: el portal está congelado.

  • Usa la guardia del portal antiguo (estado_sitio_melilla.json), no la de bomemelilla.es: termina bloqueado si melilla.es la bloquea, y sus errores no cuentan para el otro sitio.

  • Un solo turno por índice: mientras corre la sincronización de un origen, la del otro recibe en_curso_en_otro_proceso. cancelar_sincronizacion para la que esté en curso, sea del origen que sea.

  • Si un boletín está en los dos orígenes, gana el mejor resultado: con sumarios gana a sin sumarios, y este a un fallo; a igualdad, gana bomemelilla.es. Así los boletines de 2014–2016, que bomemelilla.es tiene sin sumarios, se rellenan con los del portal antiguo, y cada boletín sale una sola vez en buscar_en_indice.

  • Resultados: cada artículo trae origen: "melilla.es", url (la ficha del boletín en melilla.es) y pdf_url (el PDF de la página del artículo, para leer_pdf con url). Su bome_cve es el identificador del portal (antes de 2014 no es un CVE de bomemelilla.es; si se repite, lleva el dboid detrás, como BOME-BX-1986-1~280058) y su cve, una clave interna MEL-<dboid>-<número>. estado_indice cuenta cada origen en por_origen, guarda la última sincronización de cada uno en ultimas_sincronizaciones y muestra el origen de la que está en curso.

Dónde está y cómo rehacerlo

El índice es el fichero sumarios.sqlite3 dentro de la carpeta de datos; estado_servidor y estado_indice muestran su ruta. Para rehacerlo desde cero, cierra el cliente, borra sumarios.sqlite3 (y sumarios.sqlite3-wal / sumarios.sqlite3-shm si existen) y vuelve a llamar a sincronizar_indice. Un índice de una versión anterior de bome-navaja se migra solo al abrirlo, sin volver a descargar nada; los boletines que tenían anotado un HTTP 500 pasan a roto.


🏛️ Portal antiguo (melilla.es)

bomemelilla.es es una migración incompleta antes de 2018: de 2014 a 2017 le faltan 141 boletines (y ahí se concentran sus páginas rotas), y no tiene nada anterior a 2014. El portal antiguo del BOME en melilla.es, congelado desde marzo de 2021, conserva el catálogo entero: 3.260 boletines del 3 de enero de 1985 al 12 de marzo de 2021, con sumarios de artículos desde ~1991 y el PDF de cada página.

Qué quieres

Herramienta

Saber qué boletines hay en unas fechas

listar_bomes: antes del 13 de marzo de 2021 junta los dos catálogos (si un boletín está en los dos gana bomemelilla.es); los que solo tiene el portal antiguo traen origen: "melilla.es", su dboid y ver_con

Buscar artículos

buscar_bome_antiguo: búsqueda literal en el texto de los artículos (3–200 caracteres; no busca por número de boletín). El portal devuelve todo en una sola página, así que conviene usar términos concretos. Cada artículo trae boletín, fecha, número, tipo, sumario, consejería/dirección/sección y el PDF de cada página. Filtra por fechas (desde/hasta) y devuelve como mucho limite artículos (por defecto 100, máximo 500) con total y truncado

Ver un boletín

ver_bome_antiguo con cve o dboid: el PDF del boletín entero y sus artículos con sus páginas

Buscar con Y, O o «no contiene», o en varios años a la vez

buscar_en_indice, después de indexar el portal antiguo con sincronizar_indice y origen="melilla.es" (1991–2017 por defecto)

Leer o guardar un PDF

leer_pdf / descargar_pdf con url (solo las URL https://www.melilla.es/mandar.php/... que dan las dos herramientas anteriores)

Si ver_bome no encuentra un boletín anterior a 2022 en bomemelilla.es, su error sugiere ver_bome_antiguo.

Identificadores. Desde 2014 la numeración del portal antiguo coincide con los CVE de bomemelilla.es (BOME-B-2016-5302, BOME-BX-2021-16). Antes de 2014 los identificadores tienen la misma forma pero no son CVE de bomemelilla.es (cve_oficial: false) y algunos se repiten (24 casos, por ejemplo dos «Extra 1» en 1986): ver_bome_antiguo responde entonces boletin_ambiguo con los candidatos (dboid, fecha, sufijo), y basta con repetir con el dboid. Además, 14 boletines tienen una fecha distinta en cada sitio (por ejemplo BOME-B-2015-5230: 17-12-2015 en bomemelilla.es y 01-05-2015 en melilla.es); cita la fecha junto al origen.

robots.txt y política de uso. El robots.txt de melilla.es no permite a los robots las fichas de boletín (ficha_bome.jsp) ni los PDF (/mandar.php). Las herramientas solo los piden bajo demanda: cuando el modelo llama a una para responderte, una petición cada vez. Desde la versión 0.0.4 hay una excepción deliberada, porque el portal está congelado y puede desaparecer: la indexación del portal antiguo recorre las fichas en masa, pero solo cuando se pide con sincronizar_indice y origen="melilla.es" (nunca por su cuenta), despacio (por defecto, ~2–3 s entre peticiones), con un máximo de 250 boletines por ejecución (también por defecto) y bajo la guardia del portal. Los PDF nunca se recorren en masa: solo se piden bajo demanda.

Su propia guardia y su caché. El portal antiguo es otro sitio, así que tiene su propia guardia con las mismas reglas y los mismos ajustes (por defecto, como mucho 3 respuestas de error cada 10 minutos y 75 minutos sin pedirle nada si bloquea), guardada aparte en estado_sitio_melilla.json; sus errores nunca cuentan para bomemelilla.es, y estado_servidor la muestra en guardia_portal_antiguo. Sus herramientas van a su propio ritmo (~1–1,5 s entre peticiones, de una en una), que no se puede ajustar. El catálogo (~1 MB) se descarga con una sola petición la primera vez que hace falta y se guarda en catalogo_portal_antiguo.json; como el portal está congelado, se reutiliza siempre (estado_servidor lo muestra en catalogo_portal_antiguo; borrarlo fuerza una nueva descarga). Si el portal no responde, listar_bomes devuelve igualmente lo de bomemelilla.es con un aviso.


📖 Leer documentos largos

leer_articulo, leer_boletin y leer_pdf comparten el mismo cursor, así que un boletín de ~35 páginas nunca llega recortado en silencio:

Campo

Significado

max_caracteres

Presupuesto por llamada: entre 1000 y 100000 (por defecto 20000); un valor fuera de rango se ajusta al límite más cercano

paginas

Páginas enteras hasta llenar el presupuesto, siempre al menos una

siguiente

{desde_pagina, desde_caracter} para la siguiente llamada, o null si no queda nada

cortada

true si una página sola no cabía y se entregó un trozo; siguiente apunta dentro de esa página

sin_texto

true en páginas sin texto extraíble (escaneadas); viene con un aviso

completo

true solo si todo el documento cupo en una respuesta

Para seguir leyendo, pasa desde_pagina y desde_caracter tal cual vienen en siguiente.

leer_articulo acepta el CVE del artículo (BOME-A-2026-1051) o el del boletín más numero. Para los artículos de 2014–2016, que no tienen texto, responde con fuente: "ninguna" y un aviso.


💾 PDF descargados

  • descargar_pdf (y los lectores cuando hace falta) guardan cada PDF en la carpeta de PDF, por defecto pdfs/ dentro de la carpeta de datos.

  • El nombre del fichero es siempre el CVE canónico (BOME-P-2026-4784.pdf) o, para un PDF del portal antiguo, la ruta de su URL ya validada (https://www.melilla.es/mandar.php/n/9/4914/5302_73.pdf → melilla-9-4914-5302_73.pdf): nunca sale de datos del servidor ni de lo que escriba el modelo, y no hay parámetro para elegir otra ruta. Solo tú puedes moverla, con BOME_NAVAJA_PDF_DIR.

  • Del portal antiguo solo se aceptan URL https://www.melilla.es/mandar.php/n/<número>/<número>/<nombre>.pdf (sus enlaces http:// se pasan a https); cualquier otra se rechaza con url_pdf_invalida sin tocar la red.

  • Una copia válida en caché se reutiliza; refrescar: true fuerza la descarga. La escritura es atómica, y una descarga fallida conserva la copia anterior.

  • Límite: 100 MB por PDF (documento_demasiado_grande). Como referencia, un boletín ordinario ronda los 4 MB.


📂 Dónde guarda los datos

Sistema

Carpeta de datos por defecto

Windows

%LOCALAPPDATA%\bome-navaja (o ~\AppData\Local\bome-navaja si la variable no existe)

macOS

~/Library/Application Support/bome-navaja

Linux y otros

$XDG_DATA_HOME/bome-navaja o, si no está definida, ~/.local/share/bome-navaja

Dentro están el índice (sumarios.sqlite3), los PDF (pdfs/), el estado de la guardia del sitio (estado_sitio.json, y estado_sitio_melilla.json para el portal antiguo) y la caché del catálogo del portal antiguo (catalogo_portal_antiguo.json). Nada se crea hasta que hace falta.

Variable

Efecto

BOME_NAVAJA_DATA_DIR

Cambia la carpeta de datos entera (índice y, salvo otra indicación, PDF)

BOME_NAVAJA_PDF_DIR

Cambia solo la carpeta de PDF

Una ruta relativa en estas variables se resuelve contra el directorio de trabajo del proceso, y estado_servidor lo indica en el motivo de cada ruta; ~ se expande a tu carpeta de usuario. Un XDG_DATA_HOME relativo se ignora, como manda la especificación XDG. Con el paquete .mcpb, el ajuste Carpeta de datos fija BOME_NAVAJA_DATA_DIR; vacío equivale a no definirla.


🚀 Instalación

Hay tres caminos, de menos a más técnico. Todos necesitan uv salvo el paquete .mcpb, que Claude Desktop gestiona solo.

Opción A — Paquete .mcpb para Claude Desktop

  1. Consigue el paquete. Descarga bome-navaja-<versión>.mcpb desde la sección Releases del repositorio (la primera es v0.0.1). Otras opciones:

    • El artefacto bome-navaja-mcpb de una ejecución en verde del flujo CI (pestaña Actions del repositorio), para probar una versión sin publicar.

    • O constrúyelo desde un clon (necesitas uv y Node.js con npx): scripts/build_mcpb.sh en macOS/Linux o scripts\build_mcpb.ps1 en Windows PowerShell. El resultado queda en dist/bome-navaja-<versión>.mcpb (unos 70 KB).

  2. Haz doble clic en el archivo, o arrástralo a la ventana de Claude Desktop. Aparece el diálogo de instalación con las 19 herramientas.

  3. Opcional: en Carpeta de datos elige dónde guardar el índice y los PDF. Si la dejas vacía se usa la carpeta por defecto de tu sistema. Los demás ajustes (el ritmo con que se piden páginas y la protección frente al bloqueo del sitio) ya traen los valores recomendados: no los hagas más agresivos sin leer antes Ajustes de ritmo y protección.

  4. Acepta y reinicia Claude por completo si te lo pide.

La primera vez que arranca, Claude Desktop instala Python y las dependencias por su cuenta (unos segundos). Desde la versión 0.0.5 el paquete incluye uv.lock, así que instala las mismas versiones de las dependencias con las que se probó esa versión.

NOTE

El paqueteno está firmado, así que Claude Desktop puede mostrar una advertencia al instalarlo.

Requisito: uv

Para las opciones B y C, bome-navaja no necesita que instales Python: uv lo baja solo, junto con las dependencias, la primera vez. Instálalo una vez:

# macOS y Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows (PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

Cierra y vuelve a abrir la terminal después de instalarlo.

Opción B — Claude Code

claude mcp add bome-navaja -- uvx --from git+https://github.com/jgarcialaneitor/bome-navaja bome-navaja-mcp
IMPORTANT

El repositorio esprivado por ahora: uvx necesita que tu git tenga acceso a él (credenciales de GitHub configuradas). Si no lo tiene, clona el repositorio y usa la variante con uv run --directory de la opción C.

Opción C — Configuración manual de Claude Desktop

  1. En Claude Desktop, ve a Settings → Developer → Edit Config para abrir claude_desktop_config.json:

    • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

    • Windows: %APPDATA%\Claude\claude_desktop_config.json

  2. Añade la entrada dentro de mcpServers:

{
  "mcpServers": {
    "bome-navaja": {
      "command": "uvx",
      "args": [
        "--from",
        "git+https://github.com/jgarcialaneitor/bome-navaja",
        "bome-navaja-mcp"
      ]
    }
  }
}

O, desde un clon local (por ejemplo, si no tienes acceso git al repositorio privado):

{
  "mcpServers": {
    "bome-navaja": {
      "command": "uv",
      "args": [
        "run",
        "--directory",
        "/ruta/a/tu/clon/bome-navaja",
        "bome-navaja-mcp"
      ],
      "env": {
        "BOME_NAVAJA_DATA_DIR": "/ruta/opcional/para/los/datos"
      }
    }
  }
}

La clave env es opcional; en ella también van los ajustes de ritmo y protección.

  1. Guarda y cierra Claude por completo (no solo la ventana). Al reabrirlo deben aparecer las herramientas de bome-navaja.

Comprobar que quedó bien

Pídele al asistente:

Ejecuta estado_servidor de bome-navaja.

Debe responder con la versión, las rutas de datos, PDF e índice (y por qué se eligió cada una), si SQLite tiene FTS5 y trigram, y los ajustes en uso con sus avisos (ajustes). No toca la red ni crea el índice. Luego prueba una búsqueda real:

Busca en el BOME los artículos sobre ceses de personal eventual y cita sus CVE.

🔒 Seguridad y cortesía con el sitio

Las cifras de esta sección son los valores por defecto, que son también los recomendados; cómo cambiarlas y qué arriesgas al hacerlo está en Ajustes de ritmo y protección.

  • Pausa de cortesía entre peticiones en las herramientas (~0,5 s por defecto), con tiempos de espera acotados (30 s por defecto).

  • Un único cliente serializado para todas las herramientas: aunque el modelo lance varias a la vez, las peticiones al sitio salen de una en una.

  • La sincronización del índice va más despacio: por defecto, su propio cliente espera 2 s más una variación aleatoria de hasta 1 s entre peticiones, indexa como mucho 250 boletines por ejecución y se detiene sola (estado bloqueado) si el sitio la bloquea. La del portal antiguo va igual.

  • Guardia del sitio. El cortafuegos de bomemelilla.es bloquea la IP (en torno a una hora) tras unas 5 respuestas de error, por despacio que vayan las peticiones, y muchas son HTTP 500 de páginas de boletín rotas del propio sitio. Para no llegar a eso:

    • Entre todas las herramientas y la sincronización se admiten como mucho 3 respuestas de error (cualquier 4xx o 5xx) cada 10 minutos (valores por defecto); con el cupo lleno, la sincronización espera y las herramientas responden pausa_preventiva con reintentar_tras_segundos, sin tocar el sitio.

    • La sincronización hace una pausa de 30–60 s (por defecto) tras una página rota y no vuelve a pedir un boletín roto (su página respondió 500 dos veces) salvo con reintentar_rotos.

    • Si el sitio bloquea igualmente (403, 429 o 503, o dos peticiones seguidas sin respuesta), bome-navaja deja de tocarlo durante 75 minutos por defecto (o más, si pide Retry-After): las herramientas responden sitio_bloqueando con reintentar_tras_segundos y la sincronización termina bloqueado.

    Todos los procesos de bome-navaja comparten esta guardia y se conserva entre reinicios: vive en estado_sitio.json, en la carpeta de datos. estado_servidor la muestra en guardia_sitio. El portal antiguo de melilla.es tiene otra guardia igual pero aparte (estado_sitio_melilla.json, guardia_portal_antiguo).

  • Portal antiguo: sus PDF (que su robots.txt no permite a los robots) se piden solo bajo demanda, cuando una herramienta los necesita para responderte, nunca en masa. Sus fichas (que tampoco permite) solo se recorren en masa con la indexación del portal antiguo, que arranca solo a mano, va despacio y tiene límite por ejecución; ver Portal antiguo.

  • No recorre el sitio si no se le pide: nada al arrancar, y la sincronización solo con sincronizar_indice. Nunca corren dos sincronizaciones a la vez sobre el mismo índice, ni de dos procesos ni de dos orígenes.

  • Se identifica con un User-Agent de navegador real y no usa ni guarda credenciales.

  • El modelo no elige dónde se escribe: los PDF se nombran por su CVE canónico dentro de la carpeta configurada, y las rutas solo las cambias tú con variables de entorno.

  • stdout lleva exclusivamente JSON-RPC; los mensajes para personas van a stderr.

Ajustes de ritmo y protección

WARNING

Uso responsable. El cortafuegos de bomemelilla.es bloquea tu IP durante cerca de 1 hora tras unas 5 respuestas de error en poco tiempo, vayas al ritmo que vayas. Los valores por defecto son los recomendados y están pensados para no llegar ahí. Si pones valores más agresivos, tu IP puede acabar bloqueada y cargas más un servicio público que usa mucha gente. El servidor acepta cualquier valor válido, pero estado_servidor te lo advierte: ajustes.riesgos lista los valores más arriesgados que lo recomendado, y ajustes.avisos los que no son válidos (no son un número, son negativos, son cero donde no puede funcionar…), que se ignoran y se sustituyen por el valor por defecto.

Los nueve ajustes son los mismos para bomemelilla.es y para el portal antiguo de melilla.es (cada sitio con su propia guardia). Los cambios se aplican al reiniciar la extensión (o el servidor MCP en otros clientes): el servidor los lee una sola vez por proceso.

  • Con el paquete .mcpb: en Claude Desktop, abre la configuración de la extensión BOME Melilla — Boletín Oficial de Melilla. Cada ajuste aparece con el nombre de la tabla y una descripción con lo que hace, lo que arriesgas y el valor recomendado.

  • Con otros clientes (Claude Code, la configuración manual…): define las variables de entorno de la tabla en la configuración del servidor, por ejemplo en la clave env:

"env": {
  "BOME_NAVAJA_SYNC_DELAY": "3",
  "BOME_NAVAJA_SYNC_MAX_BOLETINES": "100"
}

Una variable vacía o sin definir usa el valor por defecto. Los decimales admiten punto o coma (0.5 o 0,5), y los recuentos, un entero escrito como 250.0. Un tiempo de más de un día (24 horas) no es válido: se usa el valor por defecto. estado_servidor muestra los valores en uso en ajustes (y el ritmo de la sincronización en cortesia_sincronizacion y cortesia_sincronizacion_portal_antiguo).

Ajuste en Claude Desktop y variable

Por defecto (recomendado)

Qué hace

Si lo haces más agresivo

Pausa entre peticiones al sincronizar (segundos)BOME_NAVAJA_SYNC_DELAY

2 (2 o más)

Segundos de espera entre cada página que pide la sincronización del índice, de los dos orígenes

Si la bajas, sincroniza antes, pero pide páginas más deprisa y el cortafuegos puede bloquear tu IP

Variación al azar de la pausa al sincronizar (segundos)BOME_NAVAJA_SYNC_JITTER

1 (1 o más)

Hasta cuántos segundos al azar se suman a cada pausa de la sincronización, para no pedir a un ritmo fijo

Si la bajas, el ritmo es más regular, más fácil de tomar por un robot y de bloquear

Máximo de boletines por sincronizaciónBOME_NAVAJA_SYNC_MAX_BOLETINES

250 (250 o menos)

Cuántos boletines procesa como mucho cada ejecución de sincronizar_indice sin max_boletines; los que falten quedan para la siguiente

Si lo subes, cada ejecución hace más peticiones seguidas y aumenta el riesgo de bloqueo

Pausa entre peticiones en las consultas (segundos)BOME_NAVAJA_QUERY_DELAY

0.5 (0,5 o más)

Segundos de espera entre peticiones de las herramientas que consultan bomemelilla.es en vivo (buscar, abrir boletines, leer artículos). Las del portal antiguo van a su propio ritmo, que no cambia

Si la bajas, las respuestas llegan antes, pero el sitio puede bloquear tu IP

Errores del sitio tolerados antes de pararBOME_NAVAJA_GUARD_MAX_ERRORS

3 (3 o menos)

Cuántas respuestas de error (4xx o 5xx) admite la guardia dentro de la ventana antes de hacer una pausa preventiva

Si lo subes, deja menos margen frente al bloqueo; con 5 o más ya no para antes de que el sitio bloquee tu IP

Ventana para contar los errores del sitio (minutos)BOME_NAVAJA_GUARD_WINDOW_MINUTES

10 (10 o más)

Minutos durante los que la guardia recuerda cada respuesta de error para contarla

Si la acortas, los errores se olvidan antes y caben más en poco tiempo, lo que acerca el bloqueo

Espera tras una señal de bloqueo (minutos)BOME_NAVAJA_GUARD_COOLDOWN_MINUTES

75 (75 o más)

Minutos sin pedir nada al sitio cuando da señales de bloqueo (403, 429 o 503, o dos peticiones seguidas sin respuesta), o más si lo pide con Retry-After

El bloqueo dura cerca de 1 hora: si esperas menos (sobre todo menos de 60), vuelves a un sitio que aún te bloquea y puedes alargar el bloqueo

Pausa tras un error del sitio al sincronizar (segundos)BOME_NAVAJA_ERROR_PAUSE_SECONDS

30 (30 o más)

Pausa mínima de la sincronización tras una página rota; la real es al azar entre este valor y el doble (30–60 s por defecto)

Si la bajas, vuelve a pedir antes, y varios errores seguidos provocan el bloqueo de tu IP

Tiempo máximo de espera de cada petición (segundos)BOME_NAVAJA_TIMEOUT

30 (30 o más)

Segundos que se espera la respuesta de cualquiera de los dos sitios antes de dar la petición por fallida

Si lo bajas, un sitio lento puede parecer bloqueado: dos peticiones seguidas sin respuesta se toman como bloqueo y se deja de pedir durante la espera tras bloqueo


🧪 Desarrollo

uv sync
uv run pytest                          # determinista, contra respuestas guardadas del sitio
BOME_NAVAJA_LIVE=1 uv run pytest       # además, los tests marcados live contra el sitio real

Los tests live consultan bomemelilla.es y se omiten salvo que definas BOME_NAVAJA_LIVE=1; la CI nunca los ejecuta.

Para construir el paquete .mcpb: scripts/build_mcpb.sh (macOS/Linux) o scripts\build_mcpb.ps1 (Windows). Ambos preparan build/mcpb con scripts/build_mcpb.py, validan el manifiesto con npx @anthropic-ai/mcpb validate y empaquetan en dist/. El manifiesto parte de mcpb/manifest.template.json.

La CI (.github/workflows/ci.yml) tiene cuatro trabajos:

Trabajo

Qué hace

test

uv run pytest en Ubuntu

test-windows

uv run pytest en Windows

bundle

Construye el .mcpb en Ubuntu y lo publica como artefacto bome-navaja-mcpb

bundle-windows

Construye el .mcpb con el script de PowerShell en Windows


🚧 Limitaciones conocidas

  • El O del sitio no funciona: su buscador trata el O como Y. buscar_bomes lo rechaza; el O solo funciona en buscar_articulos y buscar_en_indice.

  • Artículos ocultos en los extremos: los artículos que la página del boletín omite se recuperan cuando dejan un hueco en la numeración, pero no se detectan si faltan al principio o al final del boletín.

  • 2014–2016 sin texto ni PDF: solo se puede buscar en el contenido con buscar_bomes y ambito="contenido".

  • El índice solo cubre sumarios, no el texto completo de los artículos ni de los PDF. Del portal antiguo solo tiene lo que hayas indexado con sincronizar_indice y origen="melilla.es" (1991–2017 por defecto, en varias ejecuciones); los boletines anteriores a ~1991 no tienen sumarios en el portal.

  • Portal antiguo: su búsqueda es literal y sin paginar (una búsqueda muy genérica puede superar el límite de 15 MB y pide términos más concretos); los identificadores anteriores a 2014 no son CVE de bomemelilla.es y algunos se repiten; 14 boletines tienen una fecha distinta en cada sitio.

  • Claves mixtas: algunas respuestas (ver_bome, ver_sumario, listar_bomes) usan claves en inglés (number, date, sections) junto a las castellanas del resto.

  • Política de privacidad: el sitio no publica un aviso legal, así que el enlace de privacidad del paquete .mcpb apunta a su política de cookies.


📜 Licencia

MIT. Consulta LICENSE.

Available Tools

19 tools
buscar_articulosA

Búsqueda en vivo de ARTÍCULOS por su sumario: busca boletines en el sitio, abre cada uno y devuelve los artículos cuyo sumario coincide.

Misma semántica que el sitio (subcadena sin tildes ni mayúsculas; Y dentro del mismo artículo) y además admite O: terminos=[{texto, operador: "y"|"o", modo: "contiene"|"no_contiene"}]. Lenta (una petición por boletín, ~0,5 s): acotada por max_bomes (por defecto 20, máx. 100) y max_articulos (por defecto 100, máx. 500); mira 'truncado' y 'total_bomes'. Si el índice local está sincronizado, buscar_en_indice es instantánea. Recupera artículos que la página del boletín omite. Los boletines sin coincidencia local salen en 'bomes_sin_coincidencia'.

ParametersJSON Schema
NameRequiredDescriptionDefault
anioNo
desdeNo
hastaNo
textoNo
terminosNo
max_bomesNo
organismoNo
consejeriaNo
numero_bomeNo
departamentoNo
max_articulosNo
numero_articuloNo

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full behavioral burden. It discloses performance, request-per-bulletin behavior, defaults and caps, return fields to check (truncado, total_bomes, bomes_sin_coincidencia), and detailed search semantics including case/accent-insensitive substring, AND within an article, and OR via terminos.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but well-organized: purpose is front-loaded, and the following sentences pack semantics, performance, limits, alternative tool, and output hints without filler. Every sentence contributes actionable information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 12-parameter tool with no annotations and no output schema, this description is unusually complete. It covers matching rules, complex term syntax, performance trade-offs, limits, the alternative tool, and key output fields. Only minor details like date-string format and full return shape are absent, but the core calling contract is well specified.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description compensates by fully explaining the complex terminos object (texto, operador 'y'|'o', modo 'contiene'|'no_contiene') and the caps/defaults for max_bomes and max_articulos. Other parameters like anio, desde, hasta, organismo, consejeria, numero_bome, departamento, and numero_articulo are only named in the schema; their formats and ID semantics are not explained, though meanings are largely inferable.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action and resource: live search of ARTÍCULOS by their sumario, opening each bulletin and returning matching articles. It clearly differentiates from siblings by naming buscar_en_indice as the faster indexed alternative.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly warns that the tool is slow (~0.5s per bulletin) and bounded by max_bomes/max_articulos, then directs to buscar_en_indice when the local index is synchronized. It also notes a unique benefit (retrieves articles omitted by bulletin pages), though it does not enumerate formal when-not-to-use conditions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

buscar_bome_antiguoA

Busca artículos en el portal antiguo del BOME (melilla.es): boletines de 1985 al 12-03-2021, con sumarios de artículos desde ~1991.

Úsalo para cualquier cosa anterior a 2018 (bomemelilla.es está incompleto ahí y no tiene nada antes de 2014). Búsqueda literal de texto en los artículos (3-200 caracteres, sin distinguir mayúsculas; no busca por número de boletín: para eso usa ver_bome_antiguo o listar_bomes). El portal devuelve TODO en una sola página, así que usa términos concretos. Cada artículo trae cve_boletin, fecha, numero, tipo, sumario, ruta (consejería, dirección, sección), paginas (número y url_pdf de cada página: léelas con leer_pdf(url=...)), dboid_boletin y url_ficha. desde/hasta (AAAA-MM-DD o DD/MM/AAAA) filtran por la fecha del boletín después de buscar. Devuelve como mucho limite artículos (por defecto 100, máx. 500) en el orden del portal; 'total' cuenta los que pasan el filtro y 'truncado' dice si hay más: acota el texto o las fechas.

ParametersJSON Schema
NameRequiredDescriptionDefault
desdeNo
hastaNo
textoYes
limiteNo

TDQS

A5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does so thoroughly: literal case-insensitive search, no bulletin-number search, date-filtering behavior after search, portal ordering, limite default/max, and the meaning of total and truncado. It also describes the returned fields and pagination semantics.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Although long, every sentence adds operational value: scope, sibling routing, search behavior, result fields, parameter formats, and truncation handling. The structure front-loads the core purpose, then usage guidance, then parameter and return semantics.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description needs to explain return values, which it does in detail (cve_boletin, fecha, numero, ruta, paginas, url_pdf, dboid_boletin, url_ficha). It also covers coverage dates, search limitations, pagination, and how to read PDF pages with leer_pdf. This is complete for an agent to invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must fully compensate. It does: texto constraints (3-200 characters, case-insensitive), desde/hasta accepted formats (AAAA-MM-DD or DD/MM/AAAA), date-filter semantics, and limite default/maximum. This gives an agent everything needed to construct valid arguments.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Busca artículos en el portal antiguo del BOME (melilla.es)', and defines the temporal coverage. It distinguishes itself from siblings by explicitly saying it does not search by bulletin number and points to ver_bome_antiguo or listar_bomes for that.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives an explicit when-to-use rule: 'Úsalo para cualquier cosa anterior a 2018' and explains why, since bomemelilla.es is incomplete there. It also names alternatives and gives practical advice like using concrete terms because the portal returns everything on one page.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

buscar_bomesA

Búsqueda en vivo en el buscador avanzado del sitio: devuelve BOLETINES (10 por página).

texto: frase literal (subcadena, sin tildes ni mayúsculas). ambito: "sumario" (sumarios de artículos, desde finales de 2016) o "contenido" (texto de las páginas, única forma de buscar en 2014-2016). terminos: más frases [{texto, modo: "contiene"|"no_contiene", ambito?}], todas con Y y en el MISMO artículo; el sitio ignora el O, así que se rechaza (usa buscar_articulos). Fechas AAAA-MM-DD o DD/MM/AAAA (por defecto 2014-01-01..hoy). Filtros por id (listar_consejerias/listar_organismos) y números exactos. Para ver qué artículos coinciden usa buscar_articulos o buscar_en_indice.

ParametersJSON Schema
NameRequiredDescriptionDefault
anioNo
desdeNo
hastaNo
textoNo
ambitoNosumario
paginaNo
terminosNo
organismoNo
consejeriaNo
numero_bomeNo
departamentoNo
numero_paginaNo
numero_articuloNo

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full behavioral burden and does so well: pagination (10 per page), default date range (2014-01-01..today), case/accent insensitivity, AND-only termino semantics, and the site's OR-ignoring quirk are all disclosed. It also clarifies the difference between sumario and contenido scopes.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but well-organized, front-loading the purpose and return type. It packs many constraints and alternatives into a compact block; bullet formatting could improve scannability, but no sentence is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 13 parameters, no annotations, and no output schema, the description covers purpose, parameter semantics, date defaults, filters, and sibling alternatives thoroughly. It does not describe the output format beyond 'BOLETINES (10 por página),' but that may be sufficient for a search tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description compensates by explaining key parameters: texto, ambito, terminos, date formats, and filter categories (IDs and exact numbers). It doesn't enumerate every parameter individually but gives enough for correct invocation, including the shape of terminos objects.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'Búsqueda en vivo en el buscador avanzado del sitio: devuelve BOLETINES', clearly identifying the action (search) and resource (bulletins). It explicitly differentiates itself from article-level tools by noting 'Para ver qué artículos coinciden usa buscar_articulos o buscar_en_indice.'

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit routing guidance: 'el sitio ignora el O, así que se rechaza (usa buscar_articulos)' and 'Para ver qué artículos coinciden usa buscar_articulos o buscar_en_indice.' Also references listar_consejerias/listar_organismos for ID filters and notes the ambito scope for 2014-2016 content.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

buscar_en_indiceA

Búsqueda instantánea de artículos en el índice local de sumarios (sin tocar el sitio).

Requiere haber llamado antes a sincronizar_indice; si el índice está vacío devuelve 0 resultados y un aviso (usa buscar_articulos mientras tanto). Mira 'cobertura' (rango indexado, pendientes, sincronización en curso) antes de afirmar que algo no existe. La sincronización por defecto cubre desde 2018-01-01: 'pendientes' cuenta solo boletines desde esa fecha y pendientes_anteriores_2018 los anteriores del calendario sin indexar (bomemelilla.es está incompleto antes de 2018; esos boletines se consultan mejor en el portal antiguo de melilla.es). Incluye también los boletines del portal antiguo (melilla.es, 1991-2017) una vez sincronizados con sincronizar_indice(origen="melilla.es"): cada artículo trae 'origen' ("bomemelilla.es" o "melilla.es"); en los de melilla.es, url es la ficha del boletín en el portal antiguo, pdf_url el PDF de la página del artículo (léelo con leer_pdf(url=...)), bome_cve el identificador del portal (antes de 2014 no es un CVE de bomemelilla.es) y cve una clave interna MEL--. cobertura.por_origen da lo indexado de cada origen. Un boletín que está en los dos sale una sola vez, del origen con mejor resultado (con sumarios gana; a igualdad, bomemelilla.es). coincidencia: "fragmento" (subcadena, como el sitio: "cese" encuentra "ceses" y "procese") o "palabra" (cada frase debe empezar una palabra: "cese" → cese, ceses, no procese). terminos=[{texto, operador: "y"|"o", modo: "contiene"|"no_contiene"}]; Y dentro del mismo artículo. consejeria: parte del nombre (sin tildes). orden: "fecha" o "relevancia". Pagina con limite (máx. 200) y desplazamiento ('siguiente' da el próximo). Solo cubre sumarios: de bomemelilla.es desde finales de 2016 y del portal antiguo desde ~1991.

ParametersJSON Schema
NameRequiredDescriptionDefault
desdeNo
hastaNo
ordenNofecha
textoNo
limiteNo
terminosNo
consejeriaNo
coincidenciaNofragmento
desplazamientoNo
extraordinarioNo

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations and no output schema, the description carries the full burden and goes beyond it: it discloses empty-index behavior, index coverage semantics, duplicate resolution (which origin wins), matching modes with examples, AND semantics for terminos, pagination max, and scoping to summaries only.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The text is long, but every sentence carries operational value: prerequisites, coverage, duplicate handling, matching semantics, and limits. It is front-loaded with the core purpose and flows logically from setup to result interpretation, so the length is justified.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 10-parameter tool with no annotations or output schema, the description is unusually complete: it covers prerequisites, alternatives, return-field meanings, edge cases, and pagination. It still leaves a few input parameters and the full result envelope unspecified, which prevents the top score.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Despite 0% schema coverage, the description explains coincidencia values, terminos structure, consejeria matching, orden values, and pagination with max limit. It leaves desde, hasta, and especially extraordinario unstated in explicit terms, so it is not a perfect 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening line identifies the tool as immediate search of articles in the local summaries index and explicitly says it does not touch the site. It differentiates itself from siblings such as buscar_articulos and states its coverage limits (summaries only, specific date ranges).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives an explicit prerequisite (call sincronizar_indice first), tells the agent what to do if the index is empty (use buscar_articulos), and says to check cobertura before concluding something does not exist. It also names the alternative for pre-2018 bulletins (old melilla.es portal).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

cancelar_sincronizacionA

Pide parar la sincronización en curso de este proceso, sea cual sea su origen (bomemelilla.es o el portal antiguo melilla.es: cualquiera de las dos, solo corre una a la vez); termina tras el boletín que esté procesando (o al instante si está en una pausa: preventiva o tras una página rota del sitio).

Devuelve el estado de esa sincronización, con su 'origen'. Lo ya indexado se conserva y una nueva sincronizar_indice (con el mismo origen) continúa desde ahí.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It discloses the cancellation semantics (graceful stop after current bulletin, immediate stop during pause), the return value (state with 'origen'), and the persistence behavior (indexed data preserved, resumable). It does not mention side effects like whether a partially processed bulletin is kept, but the provided details are substantial.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact, front-loaded with the primary action, and every sentence adds value: the origin clarification, the stopping behavior, the return value, and the resumption guarantee. No filler or repetition of the tool name.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a parameterless tool with no output schema, the description covers the essential aspects: what it does, when it stops, what it returns, and what happens to indexed data. It could mention whether the operation is idempotent or what happens if no sync is running, but the given context is largely complete for an agent to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the schema provides no parameter semantics. The description compensates by explaining what the tool does and what it returns, which is sufficient for a parameterless action. A 4 is appropriate because there is no parameter burden to carry, and the description adds meaningful context about the operation's behavior.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's action ('Pide parar la sincronización en curso de este proceso'), the resource affected (the ongoing synchronization), and its scope (any origin, only one runs at a time). It distinguishes itself from siblings like sincronizar_indice and estado_indice by describing the cancellation behavior and its relationship to a future sync.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly explains when to use it: to stop an ongoing synchronization regardless of origin, and clarifies that it finishes the current bulletin or stops instantly during a pause. It also explains the consequence (indexed data is kept, a new sync continues from there), which helps an agent decide between this and other index-related tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

descargar_pdfA

Descarga el PDF de cualquier CVE (o, con url, uno del portal antiguo de melilla.es) a la caché local y devuelve su ruta, tamaño, sha256 y número de páginas.

Da exactamente uno: cve, o url (solo las URL https://www.melilla.es/mandar.php/... que devuelven buscar_bome_antiguo y ver_bome_antiguo). El nombre del fichero sale solo del CVE canónico o de la ruta de esa URL (melilla-9-4914-5302_73.pdf); el directorio lo fija BOME_NAVAJA_PDF_DIR (ver estado_servidor). Reutiliza la copia en caché salvo refrescar=true. Límite: 100 MB. Los PDF de 2014-2016 no existen en bomemelilla.es (404): búscalos en el portal antiguo.

ParametersJSON Schema
NameRequiredDescriptionDefault
cveNo
urlNo
refrescarNo

TDQS

A5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and covers the side effect (downloads to local cache), cache reuse unless refrescar=true, file naming from canonical CVE or URL path, directory from BOME_NAVAJA_PDF_DIR, the 100 MB limit, and the 404 behavior for 2014-2016. It even specifies the exact return tuple, so the agent knows what to expect.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Every sentence carries load-bearing constraints: parameter exclusivity, URL allowlist, file naming, cache refresh, size limit, date gap, and return fields. The description is front-loaded with the main purpose and keeps details compact.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite having no annotations and no output schema, the description supplies the return values explicitly and handles error-prone cases (2014-2016 404s, cache behavior, size limit). The only referenced external dependency, estado_servidor, is named so the agent can resolve it when needed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must add all meaning. It explains cve vs url, the exact URL restriction, the exactly-one requirement, and refrescar's effect on cache reuse. This fully compensates for the empty schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Uses a specific verb ('Descarga') and resource ('PDF de cualquier CVE o, con url, uno del portal antiguo'), and states the return values (ruta, tamaño, sha256, número de páginas). This clearly distinguishes it from reading tools such as leer_pdf and from BOME listing tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly says to provide exactly one of cve or url and restricts url to the melilla.es/mandar.php URLs emitted by buscar_bome_antiguo and ver_bome_antiguo. It also tells the agent that PDFs from 2014-2016 are 404 on bomemelilla.es and should be searched on the older portal, which is an explicit when-not/alternative.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

estado_indiceA

Estado del índice local de sumarios y de su sincronización (no toca el sitio).

Devuelve boletines indexados / sin sumarios / con error / rotos (páginas que el sitio respondió con error interno dos veces; no cuentan como pendientes), artículos, rango de fechas, pendientes frente al calendario, última sincronización y el progreso de la actual (hechos, total_planificado, eta_segundos). 'pendientes' cuenta solo boletines desde 2018-01-01 (el inicio por defecto de sincronizar_indice); los anteriores del calendario sin indexar (de sincronizaciones antiguas o con un 'desde' anterior) salen aparte en pendientes_anteriores_2018 y no son trabajo pendiente. Úsalo para seguir una sincronización lanzada con sincronizar_indice. Por origen: indice.por_origen cuenta boletines, artículos y fechas de cada origen ("bomemelilla.es" y "melilla.es", el portal antiguo) e indice.ultimas_sincronizaciones guarda el resumen de la última sincronización de cada uno (ultima_sincronizacion es la de bomemelilla.es). 'sincronizacion' es la de este proceso que está en curso (o la última lanzada), de cualquiera de los dos orígenes, con su 'origen'; indice.sincronizacion_en_curso dice qué origen sincroniza ahora cualquier proceso. Estados de la sincronización: en_curso, completado, cancelado, fallido y bloqueado (el sitio nos bloqueó: 403/429/503 o dos peticiones seguidas sin respuesta; lo indexado se conserva y bome-navaja no le pide nada durante reintentar_tras_segundos, ~75 min por defecto: no vuelvas a sincronizar antes; ver 'mensaje'). En 'mensaje' también aparecen las pausas preventivas (por defecto, como mucho 3 respuestas de error del sitio cada 10 minutos) y la sincronización cuenta los boletines que quedaron rotos en 'rotos'.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It discloses that the tool 'no toca el sitio' (does not touch the site), indicating a safe, read-only operation. It explains what counts as 'pendientes' and what is excluded, describes synchronization states (en_curso, completado, cancelado, fallido, bloqueado), and even mentions the retry behavior (~75 min) and pauses. This is comprehensive transparency about behavior and side effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but densely packed with necessary nuance. It front-loads the core purpose, then branches into details about counts, synchronization states, and per-origin info. Every sentence adds value, clarifying edge cases like the 2018 cutoff and what counts as 'pendientes'. It is appropriately sized for the tool's complexity, though it could be slightly trimmed without losing essential info.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description is exceptionally complete for a status tool. It explains the output fields (indexed boletines, without summaries, with error, broken), date ranges, pending counts and their exclusions, per-origin data, synchronization states, and even the meaning of 'mensaje'. It references sibling tool sincronizar_indice, providing context. Since there is no output schema, this description is essential and covers nearly everything an agent needs to correctly interpret and use the tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so there is nothing to document. Per the baseline for zero params, a score of 4 is appropriate. The description focuses on output semantics instead, which is useful, but parameter semantics is vacuously satisfied.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states specifically: 'Estado del índice local de sumarios y de su sincronización (no toca el sitio)'. It clearly identifies the tool as a status reader for the local index, distinct from action tools like sincronizar_indice and cancelar_sincronizacion. It also outlines the specific data returned, making its scope unmistakable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly says 'Úsalo para seguir una sincronización lanzada con sincronizar_indice', providing direct guidance on when to use it. It also warns about the 'bloqueado' state, advising not to re-sync before the retry period, which indirectly guides usage of sibling tools. However, it doesn't explicitly contrast with other read-only tools (e.g., ver_bome), but its purpose is clearly distinct, so the guidance is adequate.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

estado_servidorA

Configuración y estado del servidor, sin tocar la red ni crear el índice.

Versión, pid, rutas de datos, PDFs e índice (con el motivo de cada una: variable de entorno, XDG, LOCALAPPDATA...; las rutas relativas en BOME_NAVAJA_* se resuelven contra el directorio de trabajo), si existe el fichero del índice y su estado si ya está abierto, versión de SQLite con FTS5/trigram, URL base y:

  • ajustes: todos los ajustes que marcan cuánto se le pide a los sitios, con las variables de entorno aplicadas (un único juego para bomemelilla.es y el portal antiguo): pausa_sincronizacion_segundos y variacion_sincronizacion_segundos (ritmo de la sincronización), max_boletines_por_ejecucion, pausa_consultas_segundos (herramientas de bomemelilla.es), guardia_max_errores, guardia_ventana_minutos y guardia_enfriamiento_minutos (guardia del sitio), pausa_tras_error_segundos (la pausa tras una página rota va de ese valor al doble, pausa_tras_error_max_segundos), tiempo_espera_segundos; 'variables' dice qué variable BOME_NAVAJA_* fija cada uno, 'avisos' los valores no válidos (se usa el valor por defecto) y 'riesgos' los valores más arriesgados que lo recomendado (se usan igualmente; explícale al usuario el riesgo de bloqueo). Se leen al arrancar: cambiarlos exige reiniciar el servidor.

  • cortesia_segundos (pausa de las herramientas) y cortesia_sincronizacion (pausa, variación aleatoria y máximo de boletines por ejecución, con BOME_NAVAJA_SYNC_DELAY, BOME_NAVAJA_SYNC_JITTER y BOME_NAVAJA_SYNC_MAX_BOLETINES aplicadas, y sus avisos).

  • guardia_sitio: enfriamiento_hasta, segundos_restantes y motivo si el sitio nos bloqueó, durante el cual las herramientas responden sitio_bloqueando; errores HTTP en la ventana (ventana_segundos, 10 minutos por defecto) frente al máximo permitido (max_errores, 3 por defecto): con el cupo lleno las herramientas responden pausa_preventiva; y su fichero estado_sitio.json, compartido por todos los procesos de bome-navaja.

  • Del portal antiguo (melilla.es): url_portal_antiguo, su propia guardia (guardia_portal_antiguo, con su fichero estado_sitio_melilla.json) y la caché de su catálogo (catalogo_portal_antiguo: ruta, existe, fetched_at y número de boletines). La sincronización del portal antiguo (sincronizar_indice con origen="melilla.es") va al mismo ritmo y con el mismo máximo por ejecución que la de bomemelilla.es, con las mismas variables de entorno aplicadas: cortesia_sincronizacion_portal_antiguo (el portal interactivo va a ~1-1,5 s entre peticiones).

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full behavioral burden, and it discharges it thoroughly. It discloses that the call performs no network I/O and creates no index, that settings are read at startup and changing them requires a server restart, that it surfaces warnings for invalid and risky values ('explícale al usuario el riesgo de bloqueo'), and that some state files are shared across all processes. This is rich, honest behavioral context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose is front-loaded in the first sentence and the content is organized with bullets, but the description is extremely verbose — a dense wall of near-exhaustive field detail. While every item is arguably relevant given there is no output schema, the length pushes past 'concise' toward reference documentation; a more compressed summary would serve most callers.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given zero parameters, no annotations, and no output schema, the description is the sole source of information, and it is exceptionally complete. It enumerates every returned configuration group (sync pacing, courtesy pauses, site guard, legacy portal state) with exact variable names, defaults, and shared-file details, leaving an agent with nothing missing to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the schema carries no burden and the baseline is 4. The description instead invests heavily in explaining the return content — every config field, env var, warning category, risk class, and guard-state element — which more than compensates for the absence of an output schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific resource and verb combination: it reports server configuration and state ('Configuración y estado del servidor'), and immediately disambiguates what it is not — 'sin tocar la red ni crear el índice'. This clearly separates it from sibling tools like sincronizar_indice or buscar_articulos, giving an agent a precise sense of scope before any schema is consulted.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied rather than explicit. The negative constraint ('sin tocar la red ni crear el índice') signals that this is a safe, side-effect-free status read, which hints at when an agent would prefer it over network-touching siblings. However, it never names an alternative tool or states an explicit when/when-not condition, leaving some inference to the agent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

leer_articuloA

Texto completo de un artículo (anuncio), página a página.

cve: el CVE del artículo (BOME-A-2026-1051) o el del boletín (BOME-B-...) junto con numero (el número del artículo). Un artículo extraordinario (BOME-AX-...) se localiza sin el resolutor del sitio, que lo confunde con el artículo ordinario del mismo número: se usa el índice local si lo tiene y, si no, el calendario del año y las páginas de sus boletines extraordinarios (puede costar unas peticiones más). Nunca se devuelve un artículo distinto del pedido. Los artículos de 2014-2016 no tienen texto en el sitio: fuente="ninguna" y un aviso. Paginación: devuelve páginas enteras hasta max_caracteres (1000-100000, por defecto 20000), siempre al menos una; una página más larga que max_caracteres se corta ahí (cortada=true). Si 'siguiente' no es null, vuelve a llamar con desde_pagina y desde_caracter de 'siguiente' para continuar; null significa que no queda más.

ParametersJSON Schema
NameRequiredDescriptionDefault
cveYes
numeroNo
desde_paginaNo
desde_caracterNo
max_caracteresNo

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does so thoroughly. It discloses pagination behavior, max_caracteres limits, the cortada flag, the siguiente continuation mechanism, the 'fuente=ninguna' case for 2014-2016, and the guarantee that a different article is never returned.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but every sentence carries essential information. It is front-loaded with the main purpose, then systematically covers parameter semantics, edge cases, and pagination without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a paginated article reader with no output schema, the description is complete. It explains what the tool returns, how pagination works, how to continue with 'siguiente', and how to handle exceptional article types and missing historical text.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It explains cve, numero, max_caracteres, and the continuation parameters desde_pagina and desde_caracter through the pagination flow. It does not explicitly define the initial meaning of desde_pagina/desde_caracter, but the 'siguiente' instructions make their role clear.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'Texto completo de un artículo (anuncio), página a página', which names a specific verb, resource, and mode. It clearly separates this tool from bulletin-level tools like ver_bome or leer_boletin by focusing on individual articles and pagination.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context for when to use the tool and how to handle special cases such as extraordinary articles and 2014-2016 articles without text. It does not explicitly name sibling alternatives or exclusion conditions, but the purpose and behavior are unambiguous enough for an agent to select it correctly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

leer_boletinA

Texto completo de un boletín entero (su PDF) con los metadatos del boletín.

Un boletín ordinario tiene ~35 páginas; lee por tramos. El PDF se descarga una vez y se guarda en caché. Los boletines de 2014-2016 no tienen PDF (fuente="ninguna"): lee sus artículos con leer_articulo. Paginación: devuelve páginas enteras hasta max_caracteres (1000-100000, por defecto 20000), siempre al menos una; una página más larga que max_caracteres se corta ahí (cortada=true). Si 'siguiente' no es null, vuelve a llamar con desde_pagina y desde_caracter de 'siguiente'; null significa que no queda más.

ParametersJSON Schema
NameRequiredDescriptionDefault
cveYes
desde_paginaNo
desde_caracterNo
max_caracteresNo

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and covers caching of the PDF, pagination cut behavior (cortada=true), and the sentinel semantics of 'siguiente'. It also flags the no-PDF edge case for 2014-2016 bulletins.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but each sentence adds a distinct fact: scope, length/chunking, cache, old-bulletin exception, and pagination contract. It is front-loaded with the core purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

It explains the pagination loop, cache behavior, old-bulletin alternative, and response signals (cortada, siguiente) despite no output schema. It could be more complete by defining cve and the metadata fields returned, but the operational guidance is solid.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description defines max_caracteres with range/default and explains desde_pagina/desde_caracter through the 'siguiente' continuation contract. However, the required cve parameter is not described, so an agent must infer its meaning from sibling tools or context.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence names a specific action (leer) and resource (boletín entero/PDF) and notes it returns metadata, distinguishing it from article-level tools like leer_articulo. The later mention of 2014-2016 bulletins reinforces the boundary.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly says ordinary bulletins are ~35 pages and should be read in chunks, and instructs that 2014-2016 bulletins without PDF should be handled with leer_articulo. It also gives a concrete pagination protocol for calling again when 'siguiente' is not null.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

leer_pdfA

Texto del PDF de cualquier CVE: boletín, sumario (BOME-S), artículo (BOME-A) o página (BOME-P / BOME-PX); o, con url en vez de cve, de un PDF del portal antiguo de melilla.es.

Da exactamente uno: cve, o url (solo las URL https://www.melilla.es/mandar.php/... que devuelven buscar_bome_antiguo y ver_bome_antiguo, por página o del boletín entero; se rechaza cualquier otra). Las páginas sin texto extraíble (escaneadas, frecuentes en los boletines antiguos) salen con sin_texto=true y un aviso. Paginación: devuelve páginas enteras hasta max_caracteres (1000-100000, por defecto 20000), siempre al menos una; una página más larga que max_caracteres se corta ahí (cortada=true). Si 'siguiente' no es null, vuelve a llamar con desde_pagina y desde_caracter de 'siguiente'; null significa que no queda más.

ParametersJSON Schema
NameRequiredDescriptionDefault
cveNo
urlNo
desde_paginaNo
desde_caracterNo
max_caracteresNo

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does so thoroughly. It discloses scanned-page behavior (sin_texto=true and a warning), truncation behavior (cortada=true), page-count guarantees, and the meaning of a null 'siguiente' as end of results. This is rich behavioral detail beyond the schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but every sentence earns its place: purpose first, then input constraints, then edge-case behavior, then pagination. It is well-structured in short paragraphs and avoids filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema and no annotations, the description is remarkably complete. It covers input selection, URL restrictions, scanned-page handling, truncation, pagination continuation, and termination conditions. An agent has enough information to call the tool correctly and interpret its results.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It explains cve and url formats, the exclusivity between them, max_caracteres range and default, and how desde_pagina/desde_caracter are used for continuation. The two pagination parameters are described indirectly via 'siguiente' rather than with their own precise definitions, but the meaning is recoverable.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states exactly what the tool returns: the text of a PDF identified by a CVE or by a specific old-portal URL. It distinguishes the accepted document types (boletín, sumario, artículo, página) and the URL source, making the tool's scope clear relative to its siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit input constraints: exactly one of cve or url, only URLs returned by buscar_bome_antiguo and ver_bome_antiguo, and rejection of any other URL. It also explains the pagination loop with 'siguiente'. It does not explicitly name sibling tools as alternatives, but the context is clear enough for correct invocation.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listar_bomesA

Lista los boletines publicados entre dos fechas (calendario de bomemelilla.es y, antes de 2021-03-13, también el catálogo del portal antiguo de melilla.es).

Fechas en AAAA-MM-DD o DD/MM/AAAA, ambas incluidas. Por defecto, los últimos 30 días hasta hoy. Devuelve como máximo 500 boletines, del más reciente al más antiguo; si hay más, 'truncado' es true y 'total' dice cuántos hay: acota el rango. Cada boletín trae cve, number, date, extraordinary (BOME-BX), title, url y origen ("bomemelilla.es" o "melilla.es"). Si el rango llega antes del 2021-03-13 se añaden los boletines que solo tiene el portal antiguo (a bomemelilla.es le faltan muchos antes de 2018 y no tiene nada antes de 2014); traen dboid y ver_con (ábrelos con ver_bome_antiguo) y 'solo_portal_antiguo' los cuenta. Si un boletín está en los dos, gana bomemelilla.es (ábrelo con ver_bome). Si el portal antiguo no responde, devuelve lo de bomemelilla.es y un 'aviso'. Antes de 2014 los identificadores no son CVE de bomemelilla.es (cve_oficial=false) y pueden repetirse: usa el dboid.

ParametersJSON Schema
NameRequiredDescriptionDefault
desdeNo
hastaNo

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and succeeds: it discloses ordering, truncation semantics, deduplication ('gana bomemelilla.es'), fallback behavior when the old portal fails, the cve_oficial=false caveat before 2014, and how to open results with ver_bome/ver_bome_antiguo.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The text is dense but every sentence carries needed edge-case information, and the main action is front-loaded. It is a single monolithic paragraph rather than structured bullets, which slightly reduces scanability for an agent.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given two undocumented parameters, no annotations, and no output schema, this definition is complete: it describes return fields, format of results, source ordering, old-portal-only supplements, fallback warnings, and caveats for identifying bulletins before 2014. A caller has what it needs to invoke and interpret the tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

At 0% schema coverage, the description compensates strongly: it gives accepted date formats, inclusive bounds, default 30-day range, and the effect of wide ranges on the truncated/total fields. It does not spell out the exact behavior when only one of desde/hasta is supplied, and the schema itself has no parameter descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a precise verb and resource: 'Lista los boletines publicados entre dos fechas', and immediately scopes it to bomemelilla.es plus the old melilla.es catalog. It is clear in isolation but does not explicitly contrast with sibling search/read tools such as buscar_bomes, so the differentiation is left to context.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The tool's use case is clear: list bulletins by date range, with a default of the last 30 days, a 500-result ceiling, and instructions to narrow the range when 'truncado' is true. There is no explicit 'when not to use' or comparison to alternatives, so it stops short of 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listar_consejeriasB

Consejerías de un departamento, con su id (para filtrar buscar_bomes/buscar_articulos).

El departamento 1 es CIUDAD AUTÓNOMA DE MELILLA, el habitual.

ParametersJSON Schema
NameRequiredDescriptionDefault
departamentoYes

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description must carry behavioral disclosure. It explains the tool returns consejerías with ids and notes that department 1 is the usual one, providing useful context. But it doesn't cover output format, error behavior, or side effects, which is a moderate gap for a listing tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise at two sentences, with the core purpose front-loaded and a helpful hint appended. Every sentence contributes value, and there is no wasted text.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple listing tool with one parameter, the description covers the essential: what it returns, why it's used, and a key hint for the parameter. The absence of output schema and annotations is partially mitigated by this clear purpose, though edge cases are not addressed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must compensate. It states that department 1 is CIUDAD AUTÓNOMA DE MELILLA, which gives some meaning to the departamento parameter, but it doesn't explain valid values, ranges, or how to discover other departments. This is insufficient compensation for a completely undocumented parameter.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool lists consejerías for a department and provides their ids for filtering. It names the specific resource and purpose, distinguishing it from generic listing tools, though it doesn't explicitly compare to siblings like listar_organismos.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives a clear use case: obtaining ids to use with buscar_bomes/buscar_articulos. However, it doesn't mention alternatives or when not to use this tool, leaving some ambiguity about selection among sibling tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listar_organismosA

Organismos de una consejería, con su id (filtro 'organismo' de las búsquedas en vivo).

ParametersJSON Schema
NameRequiredDescriptionDefault
consejeriaYes

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the burden of behavioral disclosure. It usefully reveals that the returned id is meant to be used as the organismo filter, but it does not state whether this is a read-only listing, how results are ordered, or what happens if no organisms exist for the given consejería.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is one short, front-loaded sentence with no filler. It states the resource, the scope, and the practical use of the returned ids efficiently.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

This is a simple one-parameter tool, but there is no output schema and no annotations. The description conveys the core value, but it does not specify the full output shape (only that ids are present) or explain how to obtain the consejería value needed to call the tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage, the description must compensate for the undocumented parameter. It partially does so by indicating that organisms belong to a consejería, making it clear the parameter selects that consejería, but it does not explain that the integer is likely an id from listar_consejerias or specify valid value ranges.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description identifies the resource ('organismos de una consejería') and explains that the returned ids are the 'organismo' filter used in live searches. It is clear enough even without an explicit verb, and it is distinguishable from siblings like listar_consejerias, though it does not explicitly name an alternative.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'filtro organismo de las búsquedas en vivo' gives clear context: this tool is for getting organism ids to use as a search filter. It does not explicitly state when not to use it or name alternatives, but the intended use case is evident.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

resolver_cveA

Devuelve la URL canónica de cualquier CVE (boletín, artículo, sumario o página).

Útil para citar o para saber a qué boletín y artículo pertenece un CVE de artículo (BOME-A-...) o de página (BOME-P-...). Comprueba que la página exista. El resolutor del sitio confunde los extraordinarios con los ordinarios: un BOME-AX se localiza sin él (índice local o calendario del año y páginas de sus boletines extraordinarios; puede costar unas peticiones más) y se comprueba el artículo; para un BOME-PX se devuelve la URL de su PDF, con un aviso. Nunca se da por buena una redirección a un boletín del otro tipo (extraordinario frente a ordinario).

ParametersJSON Schema
NameRequiredDescriptionDefault
cveYes

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden and succeeds: it discloses validation ('Comprueba que la página exista'), the resolver's confusion between extraordinary and ordinary bulletins, the BOME-AX fallback behavior, the BOME-PX PDF-return behavior with a warning, and the strict rule about not accepting cross-type redirects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The first sentence front-loads the primary function, and the following sentences add important edge-case behavior without fluff. The description is dense and somewhat long, but every sentence contributes operational value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity and lack of annotations or output schema, the description covers purpose, parameter semantics, validation, fallback behavior, and return behavior. The main gaps are unspecified error behavior when a page does not exist and the exact shape of the returned URL or warning.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must explain the single 'cve' parameter. It does so by enumerating accepted CVE types and referencing BOME-A and BOME-P forms, which gives meaningful semantic guidance. However, it does not specify the exact accepted string format for the parameter, such as whether a prefix is required.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Devuelve') and resource ('URL canónica'), and clearly scopes the tool to any CVE (boletín, artículo, sumario o página). It also states the practical purpose ('Útil para citar o para saber a qué boletín y artículo pertenece'), which differentiates it from sibling tools that fetch or list content.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context for when the tool is useful: citing a CVE or resolving an article/page CVE to its bulletin and article. It does not explicitly name alternative sibling tools or state when not to use it, so it stops short of full exclusion guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

sincronizar_indiceA

Arranca en segundo plano la sincronización del índice local de sumarios y vuelve al instante.

origen: "bomemelilla.es" (por defecto, el sitio actual) o "melilla.es" (el portal antiguo). Solo corre una a la vez por índice, sea del origen que sea: si ya hay una sincronización en curso (de cualquiera de los dos, en este u otro proceso) devuelve su estado o en_curso_en_otro_proceso con el origen que la ocupa, sin arrancar otra.

origen="bomemelilla.es": recorre el calendario (por defecto 2018-01-01..hoy) del más reciente al más antiguo: indexa los boletines que falten, re-indexa los de los últimos reindexar_recientes_dias días y, si reintentar_errores, los que fallaron. Empieza en 2018 porque antes bomemelilla.es está incompleto e inestable (faltan boletines y sus páginas rotas responden HTTP 500, que el cortafuegos castiga) y apenas tiene texto buscable; los boletines anteriores se consultan mejor en el portal antiguo de melilla.es. Un 'desde' anterior es posible pero no recomendable. Para no saturar el sitio va despacio (~2-3 s entre peticiones) y cada ejecución indexa como mucho max_boletines boletines (por defecto 250, los más recientes; ~15-20 minutos). El rango por defecto (~1100 boletines) necesita varias ejecuciones: si el estado final trae pendientes_tras_limite > 0, vuelve a llamarla más tarde (espaciar las ejecuciones es más amable con el sitio). Es reanudable: si se corta, la siguiente llamada continúa donde quedó. Sigue el progreso con estado_indice; mientras tanto buscar_en_indice da resultados parciales. Si ya hay una en curso (en este u otro proceso) devuelve su estado sin arrancar otra. Solo sincroniza cuando se le pide. El cortafuegos del sitio bloquea la IP tras unas 5 respuestas de error, así que la sincronización admite como mucho 3 cada 10 minutos (si llega al límite hace una pausa preventiva y va más lenta) y espera 30-60 s tras una página rota (valores por defecto; los que están en uso, en estado_servidor, 'ajustes'). Si el sitio la bloquea (403/429/503 o dos peticiones seguidas sin respuesta) termina en estado "bloqueado" y bome-navaja no le pide nada durante reintentar_tras_segundos (~75 min): no la relances antes (terminaría "bloqueado" al instante). Los boletines "rotos" (su página respondió con error interno, HTTP 500, dos veces) se saltan; reintentar_rotos=True los vuelve a pedir: úsalo solo para comprobar si el sitio los arregló, porque cada uno cuesta un HTTP 500 que el cortafuegos del sitio cuenta.

origen="melilla.es" indexa los sumarios de artículos de las fichas de boletín del portal antiguo: por defecto los boletines de 1991-01-01 a 2017-12-31 (antes de 1991 las fichas no traen artículos; desde 2018 manda bomemelilla.es), del más reciente al más antiguo, y se salta los que ya están indexados con sumarios desde cualquiera de los dos orígenes. Una petición por boletín (la ficha, nunca los PDF), igual de despacio (~2-3 s entre peticiones) y con el mismo límite max_boletines (por defecto 250, ~15-20 minutos por ejecución): los ~2.000-2.500 boletines del rango necesitan varias ejecuciones espaciadas (mira pendientes_tras_limite). Es reanudable, reintenta los fallidos si reintentar_errores y los rotos solo con reintentar_rotos. reindexar_recientes_dias no se aplica (el portal está congelado). El portal antiguo tiene su propia guardia (guardia_portal_antiguo): sus errores no cuentan para bomemelilla.es. Rellena también los boletines de 2014-2016 que bomemelilla.es tiene sin sumarios.

ParametersJSON Schema
NameRequiredDescriptionDefault
desdeNo
hastaNo
origenNobomemelilla.es
max_boletinesNo
reintentar_rotosNo
reintentar_erroresNo
reindexar_recientes_diasNo

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden and does so thoroughly. It discloses asynchronous behavior, one-at-a-time execution, resumability, rate limiting (~2-3 s between requests), firewall blocking behavior, retry semantics, and what happens if a sync is already running. It even explains the blocked state and why relaunching early fails instantly.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core behavior and well organized by origin, but it is long and contains some redundancy: 'Si ya hay una en curso' appears twice, and details like 'del más reciente al más antiguo', 'Es reanudable', and 'max_boletines (por defecto 250, ~15-20 minutos)' are repeated across both origin sections. Still, nearly every sentence adds operational value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no annotations, no output schema, and 7 parameters, the description is exceptionally complete. It covers defaults, time estimates, failure modes, rate limits, blocking, retry behavior, resumability, partial results, and even where to find current settings (estado_servidor, 'ajustes'). An agent has enough context to invoke the tool correctly and interpret its outcomes.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must fully compensate, and it does. Every parameter is semantically explained: desde/hasta ranges per origin, origen variants, max_boletines default and per-execution limit, reintentar_errores, reintentar_rotos with its caveat, and reindexar_recientes_dias including the note that it does not apply to melilla.es.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Arranca en segundo plano la sincronización del índice local de sumarios y vuelve al instante.' It clearly distinguishes this from siblings like estado_indice and buscar_en_indice by emphasizing that it starts a background sync and returns immediately. The two origins are also explicitly named, leaving no ambiguity about what the tool operates on.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit when-to-use and when-not-to-use guidance: 'vuelve a llamarla más tarde' if pendientes_tras_limite > 0, 'no la relances antes' after a block, and 'úsalo solo para comprobar si el sitio los arregló' for reintentar_rotos. It also points to alternatives: 'Sigue el progreso con estado_indice; mientras tanto buscar_en_indice da resultados parciales.'

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ver_bomeA

Muestra un boletín (BOME-B-AAAA-N o BOME-BX-AAAA-N) con su árbol de artículos.

Estructura: sections (departamento) → consejerias → organismos → articles, cada artículo con cve, number, sumario, url y pdf_url. Antes de finales de 2016 los artículos no tienen sumario. La página del sitio a veces omite artículos; con recuperar_ocultos=true se buscan los huecos de numeración (una petición por hueco) y se devuelven en 'articulos_ocultos'. Para el texto de un artículo usa leer_articulo.

ParametersJSON Schema
NameRequiredDescriptionDefault
cveYes
recuperar_ocultosNo

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the behavioral burden and does so thoroughly: it discloses the return structure, the pre-2016 missing sumario quirk, the site's occasional omission of articles, and the per-gap request behavior of recuperar_ocultos.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Every sentence earns its place: main purpose first, then output structure, edge cases, and alternative tooling. Dense but not bloated.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite no output schema and no annotations, the description covers the return structure, parameter semantics, historical data caveats, and a key sibling alternative, making the tool safely invocable by an agent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, but the description compensates fully: it explains the cve format (BOME-B-AAAA-N or BOME-BX-AAAA-N) and defines recuperar_ocultos by describing exactly what happens when true and where results are returned.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific action and resource: 'Muestra un boletín ... con su árbol de artículos', and specifies the accepted CVE forms. The mention of the article tree and final routing to leer_articulo differentiates it from sibling tools such as leer_boletin and leer_articulo.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear context for when to use it (to view a bulletin with its article tree) and explicitly routes article-text requests to leer_articulo. However, it does not explicitly contrast with ver_bome_antiguo or leer_boletin, leaving some sibling selection to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ver_bome_antiguoA

Ficha de un boletín del portal antiguo (melilla.es, 1985 al 12-03-2021): PDF del boletín entero y sus artículos.

Da exactamente uno: cve (BOME-B-AAAA-N o BOME-BX-AAAA-N; se busca en el catálogo del portal) o dboid (el id del portal, como lo dan listar_bomes, buscar_bome_antiguo y los errores de ambigüedad). Antes de 2014 los identificadores tienen forma de CVE pero no son CVE de bomemelilla.es y algunos se repiten: entonces responde boletin_ambiguo con los candidatos (dboid, fecha, sufijo) y hay que repetir con su dboid. Devuelve url_pdf (el boletín entero), y articulos con numero, tipo, sumario, ruta (consejería, dirección, sección) y paginas (url_pdf de cada página). Lee cualquiera de esos PDF con leer_pdf(url=...).

ParametersJSON Schema
NameRequiredDescriptionDefault
cveNo
dboidNo

TDQS

A4.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description fully discloses behavior: returns url_pdf and articulos with specific fields, and handles ambiguity by returning candidates requiring a repeat call with dboid. This is transparent, though it does not mention error outcomes or side effects (likely none).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but well-organized: purpose first, then parameter constraints, then ambiguity note, then output details and follow-up tool. No filler; every sentence adds necessary operational info.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite complexity (ambiguity, multiple output fields, cross-tool usage), the description covers how to identify input, what the response contains, and how to use the returned PDFs. The absence of an output schema is mitigated by explicit mention of fields (numero, tipo, sumario, ruta, paginas).

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, but the description compensates entirely: explains cve format (BOME-B-AAAA-N or BOME-BX-AAAA-N), source of dboid from other tools, and nuance about pre-2014 CVEs being ambiguous. Gives meaning beyond bare parameter names.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool retrieves a bulletin from the old portal (melilla.es, 1985 to 12-03-2021) and returns both the full PDF and its articles. It uses a specific verb ('ver') and resource, and distinguishes itself from 'ver_bome' (new portal) by explicitly scoping to 'portal antiguo'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly instructs to supply exactly one of 'cve' or 'dboid', explains the CVE format and when dboid should be used, and details the ambiguity handling with 'boletin_ambiguo'. Also tells the user to use 'leer_pdf' for PDFs, giving clear alternate tool usage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ver_sumarioA

Vista web del sumario de un boletín: lista plana de artículos con su primera página.

Acepta el CVE del boletín (BOME-B/BX) o del sumario (BOME-S/SX). Aviso: en algunos boletines el sumario web es texto libre y se analiza como 0 entradas; en ese caso usa ver_bome, que es la fuente fiable de artículos y sumarios.

ParametersJSON Schema
NameRequiredDescriptionDefault
cveYes

TDQS

A4.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It does reveal an important failure mode: some bulletins have free-text summaries that are parsed as 0 entries. However, it does not describe other behavioral traits such as error handling, data source freshness, or what happens with invalid CVEs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is tight and well-structured: it opens with the core purpose, then covers parameter semantics, and closes with an important caveat and alternative. Every sentence adds necessary information without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the simplicity of the tool and the absence of an output schema, the description provides a reasonable picture: it describes the output as a flat list of articles with first-page data alert of the 0-entry fallback case. It could be more complete about error behavior or list limits, but for this single-parameter read tool it is sufficient.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema only defines the property name 'cve' with zero description coverage, so the description's parameter guidance is essential. It compensates fully by explaining that the CVE can be from a bulletin (BOME-B/BX) or a summary (BOME-S/SX), adding meaning that the schema alone completely lacks.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: it provides a web view of a bulletin's summary as a flat list of articles with their first page. It also distinguishes itself from ver_bome by identifying ver_bome as the reliable fallback for free-text summaries, helping differentiate between sibling tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly explains what input forms are accepted (bulletin CVE BOME-B/BX or summary CVE BOME-S/SX) and provides a concrete when-not-to-use condition: if the web summary is free text and returns 0 entries, use ver_bome instead. This gives clear routing guidance to an alternative tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 19 tool updatesv0.0.4
    • First observedbuscar_articulos
    • First observedbuscar_bome_antiguo
    • First observedbuscar_bomes
    • First observedbuscar_en_indice
    • First observedcancelar_sincronizacion
    • First observeddescargar_pdf
    • First observedestado_indice
    • First observedestado_servidor
    • First observedleer_articulo
    • First observedleer_boletin
    • First observedleer_pdf
    • First observedlistar_bomes
    • First observedlistar_consejerias
    • First observedlistar_organismos
    • First observedresolver_cve
    • First observedsincronizar_indice
    • First observedver_bome
    • First observedver_bome_antiguo
    • First observedver_sumario

TDQS

A4.2/5.0

Scored across 19 tools

Disambiguation4/5

Most tools map to distinct resources and actions (view bulletin, search articles, read PDF, sync index), and the descriptions carefully separate live search from local index search and old-portal tools. A few pairs could still be confused at a glance—ver_sumario vs ver_bome and leer_pdf vs leer_boletin/leer_articulo—but the descriptions resolve most ambiguity.

Naming Consistency4/5

Tool names are uniformly snake_case and mostly follow a verb_noun pattern such as ver_bome, buscar_articulos, leer_pdf, and listar_bomes. Minor deviations like estado_indice/estado_servidor and buscar_en_indice break the pure verb-first pattern, but the convention remains readable and predictable.

Tool Count4/5

19 tools is on the high side, but the server covers two distinct portals, a local search index, and PDF/read/download workflows, so each tool has a genuine role. It is slightly above the ideal 3-15 range but not bloated or redundant.

Completeness5/5

The tool surface covers the full reading workflow: listing bulletins, viewing summaries and article trees, reading articles and PDFs, downloading PDFs, resolving CVEs, searching live or in the local index, and synchronizing or canceling index sync. There are no obvious dead ends for the stated archive-search purpose.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    MCP server for searching and extracting official announcements, decrees, and resolutions from the Argentine Official Gazette (Boletín Oficial de la República Argentina). It enables LLMs to perform real-time searches and retrieve verbatim legal text with complete juridical fidelity.
    14
    19 npm
    3
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Enables querying Spain's official company registry (BORME) for company events such as incorporations, director appointments, insolvencies, and capital changes, supporting filters by date, province, and act type.
    7
    MIT