bome-navaja
Summary: This server is an MCP interface to the Boletín Oficial de la Ciudad Autónoma de Melilla (BOME), enabling search, reading, and downloading of official bulletins and articles from both the current site and the historical portal.
List and inspect bulletins: List bulletins between dates, view the department→consejería→organismo→articles tree, recover hidden articles, and see web-version summaries.
Resolve CVEs: Get canonical URLs for any bulletin, article, summary, or page CVE, with special handling for extraordinary editions.
Read documents: Read full article text, whole bulletins (from their PDF), or any PDF (by CVE or old-portal URL), paginated with a resumable cursor and character budget.
Download PDFs: Save PDFs of CVEs or old-portal URLs to a local cache, with canonical filenames, checksum, size, and page count.
Search live: Use the site's advanced search for bulletins (by summary or full content) and articles (with AND/OR logic), filtering by department, consejería, organismo, dates, and exact numbers.
Search offline: Once the local summary index is synchronized, instantly search articles with AND/OR/NOT across both sources, using substring or word-boundary matching.
Synchronize index: Start background, resumable sync of summaries from either bomemelilla.es (default 2018+) or the old portal (1991–2017), with rate limiting and pause/resume.
Access the old portal: Literal-search articles and view bulletins from melilla.es (1985–2021), with page PDFs and article summaries.
Server status: Get version, data/PDF/index paths, SQLite FTS5/trigram support, guard state, rate-limit settings, and sync progress without touching the network.
🗞️ bome-navaja
Servidor MCP para el Boletín Oficial de la Ciudad Autónoma de Melilla (BOME)
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: BOE & EUR-Lex MCP Server
🧭 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 ( |
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 |
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 |
| 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 |
| Un boletín con su árbol departamento → consejería → organismo → artículos; con | |
| La vista web del sumario, con la primera página de cada artículo (algunos sumarios son texto libre y dan 0 entradas: usa | |
| 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 ( | |
| Consejerías de un departamento con su id, para filtrar búsquedas | |
| Organismos de una consejería con su id, para filtrar búsquedas | |
Leer y descargar |
| Texto completo de un artículo, paginado |
| Texto completo de un boletín entero (su PDF) con sus metadatos, paginado | |
| Texto del PDF de cualquier CVE, o de un PDF del portal antiguo con | |
| Guarda el PDF de un CVE (o de una | |
Buscar en vivo |
| El buscador avanzado del sitio: devuelve boletines, 10 por página |
| Devuelve artículos: busca boletines, abre cada uno y se queda con los artículos cuyo sumario coincide | |
Índice local |
| 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 |
| Qué hay indexado de cada origen y cómo va la sincronización | |
| Arranca en segundo plano la sincronización del índice: de bomemelilla.es o, con | |
| Pide parar la sincronización en curso, sea del origen que sea | |
Portal antiguo |
| Búsqueda literal de artículos en melilla.es (1985–2021), con sumario y PDF de cada página |
| Un boletín del portal antiguo (por CVE o | |
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) |
|
Sin sinónimos ni variantes | Busca |
El sitio ignora el texto si no recibe fecha de inicio ( | 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 |
|
El sitio ignora el O entre términos (lo trata como Y) |
|
Los criterios numéricos son exactos | Boletín |
El buscador devuelve boletines, no artículos |
|
La página de un boletín a veces omite artículos |
|
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.
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
| Regla |
|
|
| Subcadena, igual que el sitio | cese, ceses, procese | año, humanos |
| 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
desdeanterior, 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 traependientes_tras_limitemayor 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 losroto.Sigue el progreso con
estado_indice(hechos,total_planificado,eta_segundos,rotos). Mientras tantobuscar_en_indicefunciona, pero avisa de que los resultados son parciales.cancelar_sincronizacionpara 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 yestado_indicelo cuenta aparte, no como pendiente.reintentar_rotos: truelos 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
bloqueadoybome-navajano vuelve a pedirle nada durante 75 minutos (o más, si el sitio lo pide conRetry-After);reintentar_tras_segundosdice 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 recibeen_curso_en_otro_procesocon elorigenque 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 otrodesde/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_limitedice cuántos quedan. Los ajustes de ritmo y protección (BOME_NAVAJA_SYNC_DELAY,BOME_NAVAJA_SYNC_MAX_BOLETINESy 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 losrotosolo conreintentar_rotos.reindexar_recientes_diasno se aplica: el portal está congelado.Usa la guardia del portal antiguo (
estado_sitio_melilla.json), no la de bomemelilla.es: terminabloqueadosi 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_sincronizacionpara 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) ypdf_url(el PDF de la página del artículo, paraleer_pdfconurl). Subome_cvees el identificador del portal (antes de 2014 no es un CVE de bomemelilla.es; si se repite, lleva eldboiddetrás, comoBOME-BX-1986-1~280058) y sucve, una clave internaMEL-<dboid>-<número>.estado_indicecuenta cada origen enpor_origen, guarda la última sincronización de cada uno enultimas_sincronizacionesy muestra elorigende 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 |
|
Buscar artículos |
|
Ver un boletín |
|
Buscar con Y, O o «no contiene», o en varios años a la vez |
|
Leer o guardar un PDF |
|
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 |
| Presupuesto por llamada: entre 1000 y 100000 (por defecto 20000); un valor fuera de rango se ajusta al límite más cercano |
| Páginas enteras hasta llenar el presupuesto, siempre al menos una |
|
|
|
|
|
|
|
|
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 defectopdfs/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, conBOME_NAVAJA_PDF_DIR.Del portal antiguo solo se aceptan URL
https://www.melilla.es/mandar.php/n/<número>/<número>/<nombre>.pdf(sus enlaceshttp://se pasan a https); cualquier otra se rechaza conurl_pdf_invalidasin tocar la red.Una copia válida en caché se reutiliza;
refrescar: truefuerza 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 |
|
macOS |
|
Linux y otros |
|
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 |
| Cambia la carpeta de datos entera (índice y, salvo otra indicación, PDF) |
| 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
Consigue el paquete. Descarga
bome-navaja-<versión>.mcpbdesde la sección Releases del repositorio (la primera es v0.0.1). Otras opciones:El artefacto
bome-navaja-mcpbde 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
uvy Node.js connpx):scripts/build_mcpb.shen macOS/Linux oscripts\build_mcpb.ps1en Windows PowerShell. El resultado queda endist/bome-navaja-<versión>.mcpb(unos 70 KB).
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.
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.
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.
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-mcpEl 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
En Claude Desktop, ve a Settings → Developer → Edit Config para abrir
claude_desktop_config.json:macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.json
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.
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_preventivaconreintentar_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 conreintentar_rotos.Si el sitio bloquea igualmente (403, 429 o 503, o dos peticiones seguidas sin respuesta),
bome-navajadeja de tocarlo durante 75 minutos por defecto (o más, si pideRetry-After): las herramientas respondensitio_bloqueandoconreintentar_tras_segundosy la sincronización terminabloqueado.
Todos los procesos de
bome-navajacomparten esta guardia y se conserva entre reinicios: vive enestado_sitio.json, en la carpeta de datos.estado_servidorla muestra enguardia_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.txtno 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
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) |
| 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) |
| 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ón |
| Cuántos boletines procesa como mucho cada ejecución de | Si lo subes, cada ejecución hace más peticiones seguidas y aumenta el riesgo de bloqueo |
Pausa entre peticiones en las consultas (segundos) |
| 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 parar |
| 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) |
| 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) |
| 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 | 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) |
| 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) |
| 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 realLos 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 |
|
|
|
|
| Construye el |
| Construye el |
🚧 Limitaciones conocidas
El O del sitio no funciona: su buscador trata el O como Y.
buscar_bomeslo rechaza; el O solo funciona enbuscar_articulosybuscar_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_bomesyambito="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_indiceyorigen="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
.mcpbapunta a su política de cookies.
📜 Licencia
MIT. Consulta LICENSE.
Available Tools
19 toolsbuscar_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'.
Inputs: anio, desde, hasta, texto, +8 more.
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.
Inputs: texto (required), desde, hasta, limite.
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.
Inputs: anio, desde, hasta, texto, +9 more.
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.
Inputs: desde, hasta, orden, texto, +6 more.
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í.
Inputs: no named parameters.
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.
Inputs: cve, url, refrescar.
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'.
Inputs: no named parameters.
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).
Inputs: no named parameters.
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.
Inputs: cve (required), numero, desde_pagina, desde_caracter, +1 more.
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.
Inputs: cve (required), desde_pagina, desde_caracter, max_caracteres.
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.
Inputs: cve, url, desde_pagina, desde_caracter, +1 more.
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.
Inputs: desde, hasta.
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.
Inputs: departamento (required).
listar_organismosA
Organismos de una consejería, con su id (filtro 'organismo' de las búsquedas en vivo).
Inputs: consejeria (required).
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).
Inputs: cve (required).
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.
Inputs: desde, hasta, origen, max_boletines, +3 more.
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.
Inputs: cve (required), recuperar_ocultos.
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=...).
Inputs: cve, dboid.
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.
Inputs: cve (required).
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
TDQS
Scored across 19 tools
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.
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.
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.
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
Related MCP Connectors
Search Spain's BOE/BORME gazettes, open EU funding calls and EU TED tenders. Keyless sources.
Spain's Official State Gazette (BOE) items as tagged JSON: grants, tax, public jobs, full text.
Spain's company registry gazette (BORME): more than 9.6 million events since 2009. API key or OAuth.
Subvenciones, licitaciones y boletines oficiales de España y Europa para tu IA. Gratis, sin login.
Related MCP Servers
- AlicenseBqualityCmaintenanceEnables LLMs like Claude to query the official Spanish BOE API for consolidated legislation, daily summaries, and auxiliary government tables.3159MIT
- AlicenseAqualityDmaintenanceEnables querying and analyzing Spanish (BOE) and EU (EUR-Lex) legal documents, with advanced search, PDF extraction, and cross-reference detection.851 npm2MIT
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to search Spain's consolidated legislation by title, inspect any statute's metadata and article table of contents, and read every historical version of a chosen article. Also retrieves the daily table of contents of the Spanish state gazette, grouped by section and issuing department, via the Agencia Estatal Boletín Oficial del Estado open-data API.270 npmMIT
- AlicenseAqualityCmaintenanceEnables AI clients to query Spain's official BDNS subsidy and grant listings and BOE open-data publications live, with exact counts, computed deadlines, forecast calendars, and literal PDF text of grant bases. It also surfaces BOE oposiciones and licitaciones, flagging uncertainty instead of inventing data.1064 npmMIT