Contrato luthor-datos/1 · OpenAPI 3.1 · Estado

API de datos de Luthor

Acceso programático a las tesis y leyes de Luthor para organizaciones: buscar y leer tesis, artículos de ley y la normativa del archivo por REST o por MCP, con una llave por organización, cuota mensual, excedente medido y tope de gasto.

Autenticación: Authorization: Bearer lxk_live_… en producción y lxk_test_… en el sandbox. El administrador de tu organización crea, rota y revoca las llaves; la llave se muestra una sola vez.

¿Usas Claude o ChatGPT a título personal? No necesitas llave: conecta Luthor desde tu asistente con tu cuenta de Luthor, gratis y sin tarjeta.

Conectar desde tu asistente

Para abogadas y abogados que usan Claude, Claude Code o ChatGPT a título personal: conectas Luthor con tu cuenta de Luthor, sin llave. Tu asistente pide autorización, entras en luthor.mx/conectar con tu sesión o con Google y apruebas la conexión en mcp.luthor.mx. Es el mismo endpoint (https://mcp.luthor.mx/mcp), con las mismas seis herramientas de sólo lectura. Empiezas gratis y sin tarjeta.

Una organización que integra sus sistemas usa una llave por organización.

Claude (web, escritorio y móvil)

  1. Con tu sesión de Claude abierta, usa el enlace Agregar Luthor a Claude: abre el formulario de conector personalizado con el nombre y la URL ya puestos. También puedes agregarlo a mano con la URL https://mcp.luthor.mx/mcp.
  2. Pulsa Conectar. En luthor.mx/conectar continúa con tu sesión de Luthor o con Google.
  3. Revisa el consentimiento (tu cuenta, tu plan y lo que te queda del mes) y pulsa Permitir. Vuelves a Claude ya conectado.

Lo que conectas en la web sirve también en la app de escritorio y en las de iOS y Android. En el plan gratuito de Claude cabe un solo conector personalizado. El enlace, para compartirlo:

https://claude.ai/customize/connectors?modal=add-custom-connector&connectorName=Luthor&connectorUrl=https%3A%2F%2Fmcp.luthor.mx%2Fmcp

Claude Team o Enterprise (Owner de la organización)

El Owner lo agrega una vez para toda la organización con el enlace de administración: Agregar Luthor a la organización. Después, cada miembro pulsa Conectar y entra con su cuenta de Luthor: cada persona tiene su propio plan, su propio cupo y sus propias conexiones.

https://claude.ai/admin-settings/connectors?modal=add-custom-connector&connectorName=Luthor&connectorUrl=https%3A%2F%2Fmcp.luthor.mx%2Fmcp

Claude Code

claude mcp add --transport http luthor https://mcp.luthor.mx/mcp

Sin --header ni llave: abre /mcp dentro de Claude Code, elige luthor y autentícate; se abre tu navegador con el mismo flujo. Cada computadora es una conexión aparte.

ChatGPT (modo desarrollador)

Mientras Luthor no esté en el directorio de ChatGPT, se conecta con el modo desarrollador, si tu plan lo tiene: actívalo en la configuración de aplicaciones y conectores, crea un conector con la URL https://mcp.luthor.mx/mcp y autenticación OAuth, y sigue el mismo flujo (luthor.mx/conectar → Permitir).

Planes

PlanPrecioUnidades al mesConsultas al díaDocumentos distintos en 30 días
GratisSin costo, sin tarjeta1,00030300
Luthor Conector$499 al mes, IVA incluido10,0003003,000
Incluido en tu plan IndividualSin costo adicional5,0001501,500

Una lectura cuenta 1 unidad por fragmento y una búsqueda, 5. Sin búsqueda completa: para ti, luthor_buscar_tesis es siempre la rápida, que no pasa por modelos de lenguaje, y su esquema no trae modo. Sin excedente ni cobro por uso: agotado el mes, tu asistente te dice que tu cupo se agotó y que se renueva el día 1; al llegar al límite del día, que se renueva a las 00:00 (hora de CDMX). Toda consulta admitida cuenta para el límite del día, aunque falle. Te avisamos por correo al 80 % y al 100 % del mes.

Tu plan lo decide tu cuenta de Luthor. Luthor Conector es una suscripción mensual con tarjeta que se contrata y se administra en luthor.mx/conector/. Al contratarlo, tus conexiones lo toman a más tardar en una hora, sin reconectar, y al terminar su periodo vuelven a Gratis; con el plan Individual pasa lo mismo. Si tienes los dos, rige Luthor Conector, que trae más.

Privacidad: qué se guarda y qué no

Tus conexiones y cómo revocarlas

En mcp.luthor.mx/conexiones ves cada conexión (el asistente, cuándo se conectó y su último uso) y la revocas con un clic: el corte es inmediato. La página no guarda sesión: cada visita entra por luthor.mx/conectar. Cerrar sesión en luthor.mx no revoca ninguna conexión.

Puedes tener hasta 5 conexiones activas (por ejemplo, Claude, ChatGPT y Claude Code en tu computadora), y todas comparten tu cupo. Si ya tienes 5 y conectas otra, el consentimiento te dice cuál se desconectará —la de uso más antiguo— y al pulsar Permitir se revoca antes de crear la nueva.

Conexión por cliente

Un solo endpoint MCP: https://mcp.luthor.mx/mcp (especificación 2026-07-28, sin sesiones; los clientes que aún negocian con initialize usan el carril 2025-11-25 del mismo endpoint). /mcp/ con barra final responde 404. La llave viaja siempre como Authorization: Bearer; guárdala en una variable de entorno, nunca en el código.

Claude API (conector MCP)

curl https://api.anthropic.com/v1/messages \
  -H "x-api-key: $ANTHROPIC_API_KEY" -H "anthropic-version: 2023-06-01" \
  -H "anthropic-beta: mcp-client-2025-11-20" -H "content-type: application/json" \
  -d '{
    "model": "claude-opus-5",
    "max_tokens": 4096,
    "mcp_servers": [{"type": "url", "url": "https://mcp.luthor.mx/mcp", "name": "luthor",
                     "authorization_token": "lxk_live_…"}],
    "tools": [{"type": "mcp_toolset", "mcp_server_name": "luthor"}],
    "messages": [{"role": "user", "content": "¿Qué tesis interpretan el artículo 42 del CFF?"}]
  }'

Claude Code

claude mcp add --transport http luthor https://mcp.luthor.mx/mcp \
  --header "Authorization: Bearer lxk_live_…"

OpenAI Responses

curl https://api.openai.com/v1/responses \
  -H "Authorization: Bearer $OPENAI_API_KEY" -H "Content-Type: application/json" \
  -d '{
    "model": "<tu modelo>",
    "tools": [{"type": "mcp", "server_label": "luthor", "server_url": "https://mcp.luthor.mx/mcp",
               "authorization": "lxk_live_…", "require_approval": "never"}],
    "input": "¿Qué tesis interpretan el artículo 42 del CFF?"
  }'

Cursor (.cursor/mcp.json o ~/.cursor/mcp.json)

{
  "mcpServers": {
    "luthor": {
      "url": "https://mcp.luthor.mx/mcp",
      "headers": { "Authorization": "Bearer ${env:LUTHOR_API_KEY}" }
    }
  }
}

REST

curl https://mcp.luthor.mx/v1/tesis/buscar \
  -H "Authorization: Bearer lxk_live_…" -H "Content-Type: application/json" \
  -d '{"consulta": "domicilio fiscal", "limite": 3}'

curl "https://mcp.luthor.mx/v1/articulos/CFF-art-17-H-Bis?fragmento=2" -H "Authorization: Bearer lxk_live_…"

El cuerpo de éxito de la REST es el mismo JSON que el structuredContent de la tool gemela. Esquema completo: OpenAPI 3.1.

Operaciones

Seis operaciones, gemelas en las dos puertas: misma entrada, misma salida y mismo cobro.

Buscar tesis — luthor_buscar_tesis

Busca por significado y por palabras tesis del Archivo Soberano Luthor: jurisprudencias y tesis aisladas del Poder Judicial de la Federación y, según el plan, del Tribunal Federal de Justicia Administrativa. Úsala cuando necesites criterios judiciales sobre un tema o un problema jurídico y aún no tengas el identificador de la tesis. Devuelve hasta 10 resultados con extracto, posición, puntaje, procedencia, estado y situación de la tesis, la fecha de corte del archivo y, en las del Tribunal Federal de Justicia Administrativa, a quién obligan.

REST: POST /v1/tesis/buscar (cuerpo JSON). MCP: tool luthor_buscar_tesis. Cobro: 5 unidades la rápida y 20 la completa (se cobra el modo que de verdad corrió: modo_efectivo).

Entrada

CampoTipoObligatorioDescripción
consultastringsíDe 1 a 4,000 caracteres; en modo "completa", hasta 1,000.
de 1 a 4,000 caracteres.
limiteintegernoCuántos resultados devolver.
de 1 a 10. Por omisión: 5.
modostringno«rapida»: búsqueda semántica y léxica sin modelo de lenguaje, en las tesis del Poder Judicial de la Federación. «completa»: clasifica la consulta, la expande, reordena los resultados y suma las tesis del TFJA; acepta consultas de hasta 1,000 caracteres.
Valores: rapida, completa. Por omisión: rapida.
filtrosobjectnoFiltros opcionales por época e instancia (del Poder Judicial de la Federación) y por tipo de tesis («precedente» sólo existe en el TFJA y pide el modo «completa»).
filtros.epocastringnoÉpoca de la tesis. Sin este filtro la búsqueda cubre de la Novena a la Duodécima Época (y el Tribunal Electoral); la Quinta a la Octava se buscan sólo con este filtro.
Valores: quinta, sexta, septima, octava, novena, decima, undecima, duodecima.
filtros.instanciastringnoInstancia del Poder Judicial de la Federación que emitió la tesis.
Valores: suprema_corte, plenos_regionales, plenos_de_circuito, tribunales_colegiados.
filtros.tipostringnoTipo de tesis. Filtrar por tipo exige el tipo verificado en el archivo. precedente sólo existe en el Tribunal Federal de Justicia Administrativa.
Valores: jurisprudencia, aislada, precedente.

Salida (structuredContent y cuerpo de la REST)

CampoTipoDescripción
contratostringVersión del contrato con que se produjo la respuesta.
Valores: luthor-datos/1.
resultadosarrayResultados en orden de posicion. Una búsqueda sin resultados devuelve la lista vacía y sí se cobra.
≤ 10 elementos.
resultados[].idstringIdentificador canónico. Úsalo tal cual para leer el documento.
patrón ^(?:JP-[1-9][0-9]{0,11}|TFJA-[1-9][0-9]{0,8})$.
resultados[].familiastringtesis o articulo.
Valores: tesis.
resultados[].urlstring | nullPágina pública del documento en luthor.mx, o null si no tiene.
≤ 256 caracteres; patrón ^https://luthor\.mx/.
resultados[].procedenciaobjectDe dónde sale el documento. La fuente es siempre «Archivo Soberano Luthor».
resultados[].procedencia.fuentestringAtribución obligatoria: «Archivo Soberano Luthor».
Valores: Archivo Soberano Luthor.
resultados[].procedencia.revisionstring | nullRevisión servida del documento, o null.
≤ 128 caracteres.
resultados[].procedencia.fecha_revisionstring | nullFecha de negocio de esa revisión, o null.
patrón ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$.
resultados[].procedencia.registrostringNúmero de registro de la tesis (en las del Tribunal Federal de Justicia Administrativa, su número en el archivo).
patrón ^[1-9][0-9]{0,11}$.
resultados[].procedencia.clavestringClave de la tesis.
resultados[].procedencia.epocastringÉpoca, como la trae el documento.
resultados[].procedencia.instanciastringInstancia, como la trae el documento.
resultados[].procedencia.organostring | nullÓrgano emisor, o null si el archivo no lo registra.
resultados[].procedencia.localizacionstring | nullLocalización de la publicación, o null si el archivo no la registra.
resultados[].estado_tesisobjectQué se puede afirmar del tipo de la tesis. «No registrada» no significa «vigente».
resultados[].estado_tesis.tipostringjurisprudencia, aislada o (sólo Tribunal Federal de Justicia Administrativa) precedente cuando está verificado; si no, NO_VERIFICADO.
Valores: jurisprudencia, aislada, precedente, NO_VERIFICADO.
resultados[].estado_tesis.origen_tipostring | nullDe dónde sale el tipo afirmado; null si no se afirma.
Valores: registro_del_archivo.
resultados[].estado_tesis.interrupcion_o_superacionstringSi el archivo registra una interrupción, superación, abandono o suspensión de la tesis (o, en el corpus curado, su lista de superadas). «No registrada» no significa «vigente».
Valores: registrada, no_registrada_en_corpus.
resultados[].estado_tesis.causastring | nullPor qué el tipo no está verificado; null si lo está.
Valores: SIN_REGISTRO_EN_ARCHIVO, ARCHIVO_NO_DISPONIBLE.
resultados[].rubrostringRubro de la tesis.
resultados[].texto_transformadobooleantrue si el saneador modificó el texto servido.
resultados[].extractostringExtracto del texto para la búsqueda.
≤ 1,200 caracteres.
resultados[].truncadoobjectSi el extracto es más corto que el texto.
resultados[].truncado.truncadobooleantrue si el extracto no es el texto completo.
Valores: false, true.
resultados[].truncado.motivostring | nullEXTRACTO si se recortó; si no, null.
Valores: EXTRACTO.
resultados[].truncado.fragmentonullFragmento entregado (base 1); null en un extracto.
resultados[].truncado.fragmentos_totalesnullCuántos fragmentos tiene el documento; null en un extracto.
resultados[].truncado.bytes_entregadosintegerBytes UTF-8 del texto entregado.
≥ 0.
resultados[].truncado.bytes_totalesintegerBytes UTF-8 del texto completo.
≥ 0.
resultados[].posicionintegerLugar en la lista, desde 1.
de 1 a 10.
resultados[].puntajenumberPuntaje del criterio de ranking. Sólo compara resultados de la misma respuesta.
resultados[].criterio_rankingstringQué ordena la lista: semantico, hibrido (búsqueda semántica y por palabras fundidas por rango; su puntaje sólo ordena), semantico_reordenado (búsqueda completa) o lexico_posicional (artículos).
Valores: semantico, semantico_reordenado, hibrido.
resultados[].coleccionstringOpcional (desde luthor-datos/1.2): de qué colección sale la tesis: archivo (Poder Judicial de la Federación), tfja (Tribunal Federal de Justicia Administrativa) o curado.
Valores: curado, archivo, tfja.
resultados[].pesostringOpcional (desde luthor-datos/1.2), sólo en tesis del Tribunal Federal de Justicia Administrativa: a quién obliga, con su artículo (su jurisprudencia obliga sólo a sus Salas y cede ante la del Poder Judicial de la Federación).
resultados[].situacionstringOpcional (desde luthor-datos/1.2): lo que el archivo registra de la tesis en una línea (abandonos, sustituciones, suspensiones o las notas de su propia ficha), con su fecha. Nunca afirma que la tesis siga obligando.
modo_efectivostringEl modo que de verdad corrió. Una completa que se degradó (p. ej. sin reordenamiento disponible) declara rapida y se cobra como rápida.
Valores: rapida, completa.
truncadoobjectSi la lista se recortó para caber en el techo de salida.
truncado.truncadobooleantrue si se entregaron menos resultados, o extractos más cortos, de los que había.
Valores: false, true.
truncado.motivostring | nullPor qué se recortó; null si no se recortó.
Valores: TECHO_DE_SALIDA.
truncado.resultados_entregadosintegerCuántos resultados trae la respuesta.
de 0 a 10.
truncado.resultados_candidatosintegerCuántos había antes del recorte.
≥ 0.
truncado.extracto_max_caracteresintegerLargo máximo que se usó para los extractos de esta respuesta.
de 0 a 1,200.
corpusobjectQué colección sirvió la respuesta y de qué fecha es.
corpus.coleccionstringarchivo (desde luthor-datos/1.2): las tesis salen del Archivo Soberano Luthor completo. curado: los artículos, y las tesis cuando el archivo no está disponible y la búsqueda cae al corpus curado.
Valores: curado, archivo.
corpus.cortestring | nullFecha de negocio (AAAA-MM-DD) de la última publicación que tocó esta familia (tesis o artículos), o el corte declarado del archivo. null si no se pudo leer. No se promete frescura: revísala.
patrón ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$.
corpus.revisionstring | nullIdentificador de esa publicación o de la revisión del archivo, o null.
≤ 128 caracteres.

Leer tesis — luthor_leer_tesis

Lee una tesis del Archivo Soberano Luthor por su identificador (JP-… del Poder Judicial de la Federación o, según el plan, TFJA-… del Tribunal Federal de Justicia Administrativa). Úsala cuando ya tengas el identificador de la tesis (p. ej. de un resultado de luthor_buscar_tesis) y necesites su texto para citarla o analizarla. Devuelve el texto por fragmentos fijos, con procedencia, estado y situación de la tesis, el truncado declarado y la fecha de corte del archivo.

REST: GET /v1/tesis/{id} (con ?fragmento=N opcional; el id va sólo en la ruta). MCP: tool luthor_leer_tesis. Cobro: 1 unidad por fragmento entregado.

Entrada

CampoTipoObligatorioDescripción
idstringsíIdentificador de la tesis, p. ej. JP-159807 (Poder Judicial de la Federación) o TFJA-48288 (Tribunal Federal de Justicia Administrativa).
patrón ^(?:JP-[1-9][0-9]{0,11}|TFJA-[1-9][0-9]{0,8})$.
fragmentointegernoFragmento del documento, base 1. Los fragmentos son fijos por documento; cada uno es una lectura.
de 1 a 100,000. Por omisión: 1.

Salida (structuredContent y cuerpo de la REST)

CampoTipoDescripción
contratostringVersión del contrato con que se produjo la respuesta.
Valores: luthor-datos/1.
documentoobjectEl documento leído, con su sobre común.
documento.idstringIdentificador canónico. Úsalo tal cual para leer el documento.
patrón ^(?:JP-[1-9][0-9]{0,11}|TFJA-[1-9][0-9]{0,8})$.
documento.familiastringtesis o articulo.
Valores: tesis.
documento.urlstring | nullPágina pública del documento en luthor.mx, o null si no tiene.
≤ 256 caracteres; patrón ^https://luthor\.mx/.
documento.procedenciaobjectDe dónde sale el documento. La fuente es siempre «Archivo Soberano Luthor».
documento.procedencia.fuentestringAtribución obligatoria: «Archivo Soberano Luthor».
Valores: Archivo Soberano Luthor.
documento.procedencia.revisionstring | nullRevisión servida del documento, o null.
≤ 128 caracteres.
documento.procedencia.fecha_revisionstring | nullFecha de negocio de esa revisión, o null.
patrón ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$.
documento.procedencia.registrostringNúmero de registro de la tesis (en las del Tribunal Federal de Justicia Administrativa, su número en el archivo).
patrón ^[1-9][0-9]{0,11}$.
documento.procedencia.clavestringClave de la tesis.
documento.procedencia.epocastringÉpoca, como la trae el documento.
documento.procedencia.instanciastringInstancia, como la trae el documento.
documento.procedencia.organostring | nullÓrgano emisor, o null si el archivo no lo registra.
documento.procedencia.localizacionstring | nullLocalización de la publicación, o null si el archivo no la registra.
documento.estado_tesisobjectQué se puede afirmar del tipo de la tesis. «No registrada» no significa «vigente».
documento.estado_tesis.tipostringjurisprudencia, aislada o (sólo Tribunal Federal de Justicia Administrativa) precedente cuando está verificado; si no, NO_VERIFICADO.
Valores: jurisprudencia, aislada, precedente, NO_VERIFICADO.
documento.estado_tesis.origen_tipostring | nullDe dónde sale el tipo afirmado; null si no se afirma.
Valores: registro_del_archivo.
documento.estado_tesis.interrupcion_o_superacionstringSi el archivo registra una interrupción, superación, abandono o suspensión de la tesis (o, en el corpus curado, su lista de superadas). «No registrada» no significa «vigente».
Valores: registrada, no_registrada_en_corpus.
documento.estado_tesis.causastring | nullPor qué el tipo no está verificado; null si lo está.
Valores: SIN_REGISTRO_EN_ARCHIVO, ARCHIVO_NO_DISPONIBLE.
documento.rubrostringRubro de la tesis.
documento.texto_transformadobooleantrue si el saneador modificó el texto servido.
documento.textostringTexto del fragmento pedido, saneado. Concatenar todos los fragmentos da el texto completo.
documento.truncadoobjectSi el documento se entregó por fragmentos.
documento.truncado.truncadobooleantrue si el documento tiene más de un fragmento.
Valores: false, true.
documento.truncado.motivostring | nullFRAGMENTADO si tiene más de un fragmento; si no, null.
Valores: FRAGMENTADO.
documento.truncado.fragmentointegerFragmento entregado (base 1); null en un extracto.
Valores: 1. ≥ 1.
documento.truncado.fragmentos_totalesintegerCuántos fragmentos tiene el documento; null en un extracto.
Valores: 1. ≥ 2.
documento.truncado.bytes_entregadosintegerBytes UTF-8 del texto entregado.
≥ 0.
documento.truncado.bytes_totalesintegerBytes UTF-8 del texto completo.
≥ 0.
documento.coleccionstringOpcional (desde luthor-datos/1.2): de qué colección sale la tesis: archivo (Poder Judicial de la Federación), tfja (Tribunal Federal de Justicia Administrativa) o curado.
Valores: curado, archivo, tfja.
documento.pesostringOpcional (desde luthor-datos/1.2), sólo en tesis del Tribunal Federal de Justicia Administrativa: a quién obliga, con su artículo (su jurisprudencia obliga sólo a sus Salas y cede ante la del Poder Judicial de la Federación).
documento.situacionstringOpcional (desde luthor-datos/1.2): lo que el archivo registra de la tesis en una línea (abandonos, sustituciones, suspensiones o las notas de su propia ficha), con su fecha. Nunca afirma que la tesis siga obligando.
corpusobjectQué colección sirvió la respuesta y de qué fecha es.
corpus.coleccionstringarchivo (desde luthor-datos/1.2): las tesis salen del Archivo Soberano Luthor completo. curado: los artículos, y las tesis cuando el archivo no está disponible y la búsqueda cae al corpus curado.
Valores: curado, archivo.
corpus.cortestring | nullFecha de negocio (AAAA-MM-DD) de la última publicación que tocó esta familia (tesis o artículos), o el corte declarado del archivo. null si no se pudo leer. No se promete frescura: revísala.
patrón ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$.
corpus.revisionstring | nullIdentificador de esa publicación o de la revisión del archivo, o null.
≤ 128 caracteres.

Buscar artículos — luthor_buscar_articulo

Busca por coincidencia léxica artículos de las 16 leyes de Luthor. Úsala cuando necesites saber qué artículos regulan un tema y no conozcas su número, en todas las leyes o en una sola. Devuelve hasta 10 resultados con extracto, URL, posición, puntaje, procedencia y vigencia.

REST: POST /v1/articulos/buscar (cuerpo JSON). MCP: tool luthor_buscar_articulo. Cobro: 5 unidades (es léxica: siempre rápida).

Entrada

CampoTipoObligatorioDescripción
consultastringsíTexto a buscar, en español.
de 1 a 4,000 caracteres.
limiteintegernoCuántos resultados devolver.
de 1 a 10. Por omisión: 5.
leystringnoCódigo de ley del catálogo de 16 ordenamientos.
Valores: CFF, LISR, LIVA, LFPCA, RCFF, RLISR, RLIVA, RMF-2026, LAMP, LOTFJA, CPEUM, RISAT, LFT, CNPP, CPF, CCOM.

Salida (structuredContent y cuerpo de la REST)

CampoTipoDescripción
contratostringVersión del contrato con que se produjo la respuesta.
Valores: luthor-datos/1.
resultadosarrayResultados en orden de posicion. Una búsqueda sin resultados devuelve la lista vacía y sí se cobra.
≤ 10 elementos.
resultados[].idstringIdentificador canónico. Úsalo tal cual para leer el documento.
≤ 64 caracteres; patrón ^(?:[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*-(?:art|cap)-[A-Za-z0-9.]+(?:-[A-Za-z0-9]+)*|[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*-transitorios|RMF-[0-9]{4}-00-glosario|RMF-[0-9]{4}-01-tit-[0-9]+|RMF-[0-9]{4}-anexo-[0-9]+|decreto(?:-[a-z0-9]+)+)$.
resultados[].familiastringtesis o articulo.
Valores: articulo.
resultados[].urlstring | nullPágina pública del documento en luthor.mx, o null si no tiene.
≤ 256 caracteres; patrón ^https://luthor\.mx/.
resultados[].procedenciaobjectDe dónde sale el documento. La fuente es siempre «Archivo Soberano Luthor».
resultados[].procedencia.fuentestringAtribución obligatoria: «Archivo Soberano Luthor».
Valores: Archivo Soberano Luthor.
resultados[].procedencia.revisionstring | nullRevisión servida del documento, o null.
≤ 128 caracteres.
resultados[].procedencia.fecha_revisionstring | nullFecha de negocio de esa revisión, o null.
patrón ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$.
resultados[].procedencia.leystring | nullNombre del ordenamiento, o null para material auxiliar.
resultados[].procedencia.codigo_leystring | nullCódigo del ordenamiento en el catálogo de 16, o null.
Valores: CFF, LISR, LIVA, LFPCA, RCFF, RLISR, RLIVA, RMF-2026, LAMP, LOTFJA, CPEUM, RISAT, LFT, CNPP, CPF, CCOM.
resultados[].procedencia.numerostringNúmero del artículo o de la regla.
≤ 64 caracteres.
resultados[].vigenciaobjectQué se puede afirmar de la vigencia del artículo, en forma compacta: estado, fuente, causa, granularidad y fecha de corte. La última reforma y la versión cotejada vienen al leer el artículo. Nunca se infiere «vigente» del éxito de la llamada.
resultados[].vigencia.estadostringvigente o derogado sólo con fuente; si no, NO_VERIFICADO con causa.
Valores: vigente, derogado, NO_VERIFICADO.
resultados[].vigencia.fuentestring | nullDe dónde sale el estado afirmado: texto_servido (el texto ES la derogación), bitacora_de_revisiones o cotejo_con_archivo (el texto es idéntico al del mismo artículo en la última versión del ordenamiento en el Archivo Soberano Luthor, sin reforma posterior registrada). null si no se afirma.
Valores: texto_servido, bitacora_de_revisiones, cotejo_con_archivo.
resultados[].vigencia.causastring | nullPor qué no está verificada; null si lo está. DIFIERE_DEL_ARCHIVO: el texto no es idéntico al de la versión cotejada. COTEJO_DESACTUALIZADO: no hay una revisión reciente de reformas de la ley, o se registró una reforma posterior a la versión cotejada.
Valores: SIN_HISTORIAL, VIGENCIA_SOLO_POR_LEY, AVISO_DIFERIDO_PENDIENTE, DIFIERE_DEL_ARCHIVO, COTEJO_DESACTUALIZADO.
resultados[].vigencia.granularidadstringSi la vigencia es del artículo o sólo de la ley completa.
Valores: articulo, ley.
resultados[].vigencia.fecha_cortestring | nullFecha de negocio a la que se refiere la vigencia, o null. Con el cotejo, el día de la última revisión de reformas de la ley.
patrón ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$.
resultados[].titulostringTítulo del artículo.
resultados[].texto_transformadobooleantrue si el saneador modificó el texto servido.
resultados[].extractostringExtracto del texto para la búsqueda.
≤ 1,200 caracteres.
resultados[].truncadoobjectSi el extracto es más corto que el texto.
resultados[].truncado.truncadobooleantrue si el extracto no es el texto completo.
Valores: false, true.
resultados[].truncado.motivostring | nullEXTRACTO si se recortó; si no, null.
Valores: EXTRACTO.
resultados[].truncado.fragmentonullFragmento entregado (base 1); null en un extracto.
resultados[].truncado.fragmentos_totalesnullCuántos fragmentos tiene el documento; null en un extracto.
resultados[].truncado.bytes_entregadosintegerBytes UTF-8 del texto entregado.
≥ 0.
resultados[].truncado.bytes_totalesintegerBytes UTF-8 del texto completo.
≥ 0.
resultados[].posicionintegerLugar en la lista, desde 1.
de 1 a 10.
resultados[].puntajenumberPuntaje del criterio de ranking. Sólo compara resultados de la misma respuesta.
resultados[].criterio_rankingstringQué ordena la lista: semantico, hibrido (búsqueda semántica y por palabras fundidas por rango; su puntaje sólo ordena), semantico_reordenado (búsqueda completa) o lexico_posicional (artículos).
Valores: lexico_posicional.
modo_efectivostringEl modo que de verdad corrió. Una completa que se degradó (p. ej. sin reordenamiento disponible) declara rapida y se cobra como rápida.
Valores: rapida.
truncadoobjectSi la lista se recortó para caber en el techo de salida.
truncado.truncadobooleantrue si se entregaron menos resultados, o extractos más cortos, de los que había.
Valores: false, true.
truncado.motivostring | nullPor qué se recortó; null si no se recortó.
Valores: TECHO_DE_SALIDA.
truncado.resultados_entregadosintegerCuántos resultados trae la respuesta.
de 0 a 10.
truncado.resultados_candidatosintegerCuántos había antes del recorte.
≥ 0.
truncado.extracto_max_caracteresintegerLargo máximo que se usó para los extractos de esta respuesta.
de 0 a 1,200.
corpusobjectQué colección sirvió la respuesta y de qué fecha es.
corpus.coleccionstringarchivo (desde luthor-datos/1.2): las tesis salen del Archivo Soberano Luthor completo. curado: los artículos, y las tesis cuando el archivo no está disponible y la búsqueda cae al corpus curado.
Valores: curado, archivo.
corpus.cortestring | nullFecha de negocio (AAAA-MM-DD) de la última publicación que tocó esta familia (tesis o artículos), o el corte declarado del archivo. null si no se pudo leer. No se promete frescura: revísala.
patrón ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$.
corpus.revisionstring | nullIdentificador de esa publicación o de la revisión del archivo, o null.
≤ 128 caracteres.

Leer artículo — luthor_leer_articulo

Lee un artículo de las 16 leyes de Luthor, por identificador o por ley y número. Úsala cuando necesites el texto de un artículo o de una regla que ya identificaste, p. ej. para citarlo o revisar su vigencia. Devuelve el texto por fragmentos fijos, con procedencia, vigencia y el truncado declarado.

REST: GET /v1/articulos/{id} (con ?fragmento=N opcional; el id va sólo en la ruta). MCP: tool luthor_leer_articulo. Cobro: 1 unidad por fragmento entregado.

Por MCP se pide con id o con ley y articulo, nunca con los dos.

Entrada

CampoTipoObligatorioDescripción
idstringnoIdentificador del artículo, p. ej. CFF-art-17-H-Bis o RMF-2026-cap-2.1.1.
≤ 64 caracteres; patrón ^(?:[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*-(?:art|cap)-[A-Za-z0-9.]+(?:-[A-Za-z0-9]+)*|[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*-transitorios|RMF-[0-9]{4}-00-glosario|RMF-[0-9]{4}-01-tit-[0-9]+|RMF-[0-9]{4}-anexo-[0-9]+|decreto(?:-[a-z0-9]+)+)$.
leystringnoCódigo de ley del catálogo de 16 ordenamientos. Va con articulo y sin id.
Valores: CFF, LISR, LIVA, LFPCA, RCFF, RLISR, RLIVA, RMF-2026, LAMP, LOTFJA, CPEUM, RISAT, LFT, CNPP, CPF, CCOM.
articulostringnoNúmero del artículo o de la regla, p. ej. 42 o 2.1.1. Va con ley y sin id.
de 1 a 40 caracteres; patrón ^[0-9A-Za-z][0-9A-Za-z.-]*$.
fragmentointegernoFragmento del documento, base 1. Los fragmentos son fijos por documento; cada uno es una lectura.
de 1 a 100,000. Por omisión: 1.

Salida (structuredContent y cuerpo de la REST)

CampoTipoDescripción
contratostringVersión del contrato con que se produjo la respuesta.
Valores: luthor-datos/1.
documentoobjectEl documento leído, con su sobre común.
documento.idstringIdentificador canónico. Úsalo tal cual para leer el documento.
≤ 64 caracteres; patrón ^(?:[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*-(?:art|cap)-[A-Za-z0-9.]+(?:-[A-Za-z0-9]+)*|[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*-transitorios|RMF-[0-9]{4}-00-glosario|RMF-[0-9]{4}-01-tit-[0-9]+|RMF-[0-9]{4}-anexo-[0-9]+|decreto(?:-[a-z0-9]+)+)$.
documento.familiastringtesis o articulo.
Valores: articulo.
documento.urlstring | nullPágina pública del documento en luthor.mx, o null si no tiene.
≤ 256 caracteres; patrón ^https://luthor\.mx/.
documento.procedenciaobjectDe dónde sale el documento. La fuente es siempre «Archivo Soberano Luthor».
documento.procedencia.fuentestringAtribución obligatoria: «Archivo Soberano Luthor».
Valores: Archivo Soberano Luthor.
documento.procedencia.revisionstring | nullRevisión servida del documento, o null.
≤ 128 caracteres.
documento.procedencia.fecha_revisionstring | nullFecha de negocio de esa revisión, o null.
patrón ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$.
documento.procedencia.leystring | nullNombre del ordenamiento, o null para material auxiliar.
documento.procedencia.codigo_leystring | nullCódigo del ordenamiento en el catálogo de 16, o null.
Valores: CFF, LISR, LIVA, LFPCA, RCFF, RLISR, RLIVA, RMF-2026, LAMP, LOTFJA, CPEUM, RISAT, LFT, CNPP, CPF, CCOM.
documento.procedencia.numerostringNúmero del artículo o de la regla.
≤ 64 caracteres.
documento.vigenciaobjectQué se puede afirmar de la vigencia del artículo. Nunca se infiere «vigente» del éxito de la llamada.
documento.vigencia.estadostringvigente o derogado sólo con fuente; si no, NO_VERIFICADO con causa.
Valores: vigente, derogado, NO_VERIFICADO.
documento.vigencia.fuentestring | nullDe dónde sale el estado afirmado: texto_servido (el texto ES la derogación), bitacora_de_revisiones o cotejo_con_archivo (el texto es idéntico al del mismo artículo en la última versión del ordenamiento en el Archivo Soberano Luthor, sin reforma posterior registrada). null si no se afirma.
Valores: texto_servido, bitacora_de_revisiones, cotejo_con_archivo.
documento.vigencia.causastring | nullPor qué no está verificada; null si lo está. DIFIERE_DEL_ARCHIVO: el texto no es idéntico al de la versión cotejada. COTEJO_DESACTUALIZADO: no hay una revisión reciente de reformas de la ley, o se registró una reforma posterior a la versión cotejada.
Valores: SIN_HISTORIAL, VIGENCIA_SOLO_POR_LEY, AVISO_DIFERIDO_PENDIENTE, DIFIERE_DEL_ARCHIVO, COTEJO_DESACTUALIZADO.
documento.vigencia.granularidadstringSi la vigencia es del artículo o sólo de la ley completa.
Valores: articulo, ley.
documento.vigencia.fecha_cortestring | nullFecha de negocio a la que se refiere la vigencia, o null. Con el cotejo, el día de la última revisión de reformas de la ley.
patrón ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$.
documento.vigencia.ultima_reformastring | nullSólo al leer el artículo, siempre con cotejo_con_archivo: fecha de negocio (AAAA-MM-DD) de la última reforma, adición o derogación que la versión cotejada registra para el artículo; null si no registra ninguna (texto original).
patrón ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$.
documento.vigencia.version_cotejadastringSólo al leer el artículo: fecha de publicación (AAAA-MM-DD) de la versión del ordenamiento contra la que se cotejó el texto. Siempre con cotejo_con_archivo; con DIFIERE_DEL_ARCHIVO o COTEJO_DESACTUALIZADO, cuando se conoce.
patrón ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$.
documento.titulostringTítulo del artículo.
documento.texto_transformadobooleantrue si el saneador modificó el texto servido.
documento.textostringTexto del fragmento pedido, saneado. Concatenar todos los fragmentos da el texto completo.
documento.truncadoobjectSi el documento se entregó por fragmentos.
documento.truncado.truncadobooleantrue si el documento tiene más de un fragmento.
Valores: false, true.
documento.truncado.motivostring | nullFRAGMENTADO si tiene más de un fragmento; si no, null.
Valores: FRAGMENTADO.
documento.truncado.fragmentointegerFragmento entregado (base 1); null en un extracto.
Valores: 1. ≥ 1.
documento.truncado.fragmentos_totalesintegerCuántos fragmentos tiene el documento; null en un extracto.
Valores: 1. ≥ 2.
documento.truncado.bytes_entregadosintegerBytes UTF-8 del texto entregado.
≥ 0.
documento.truncado.bytes_totalesintegerBytes UTF-8 del texto completo.
≥ 0.
corpusobjectQué colección sirvió la respuesta y de qué fecha es.
corpus.coleccionstringarchivo (desde luthor-datos/1.2): las tesis salen del Archivo Soberano Luthor completo. curado: los artículos, y las tesis cuando el archivo no está disponible y la búsqueda cae al corpus curado.
Valores: curado, archivo.
corpus.cortestring | nullFecha de negocio (AAAA-MM-DD) de la última publicación que tocó esta familia (tesis o artículos), o el corte declarado del archivo. null si no se pudo leer. No se promete frescura: revísala.
patrón ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$.
corpus.revisionstring | nullIdentificador de esa publicación o de la revisión del archivo, o null.
≤ 128 caracteres.

Buscar ordenamientos — luthor_buscar_ordenamiento

Busca por palabras normas del Archivo Soberano Luthor: leyes, códigos, reglamentos, decretos y tratados de todo México (federales, de las 32 entidades federativas e internacionales). Úsala cuando necesites ubicar una norma que no está en las 16 leyes de Luthor, p. ej. una ley estatal, un código civil local o un tratado, y aún no tengas su identificador. Devuelve hasta 10 normas con su identificador ORD-, título, ámbito, entidad y categoría, la vigencia declarada con su fuente y su fecha de corte, y la versión vigente con el tipo de texto que tiene.

REST: POST /v1/ordenamientos/buscar (cuerpo JSON). MCP: tool luthor_buscar_ordenamiento. Cobro: 5 unidades (es léxica: siempre rápida).

Entrada

CampoTipoObligatorioDescripción
consultastringsíPalabras del nombre de la norma o de su materia (p. ej. «código civil», «ley de hacienda municipal»), de 1 a 200 caracteres. Hoy se busca en la ficha del catálogo (título, categoría y materia).
de 1 a 200 caracteres.
limiteintegernoCuántos resultados devolver.
de 1 a 10. Por omisión: 5.
filtrosobjectnoFiltros opcionales por ámbito, entidad federativa, categoría y vigencia declarada.
filtros.ambitostringnoFederal, estatal o tratados internacionales.
Valores: federal, estatal, tratados.
filtros.entidadstringnoEntidad federativa (sólo normas estatales). Hay una norma homónima por entidad: úsalo cuando la consulta nombra un estado.
filtros.categoriastringnoCategoría de la norma.
Valores: ley, reglamento, codigo, constitucion, decreto, acuerdo, presupuesto, plan, programa, manual, bando, estatuto, lineamientos, convenio, convencion, tratado, protocolo, declaratoria.
filtros.vigenciastringnoEstado de vigencia DECLARADO de la norma (la etiqueta del catálogo a su fecha de corte, no verificada).
Valores: vigente, no_vigente, abrogado, derogado, sin_efecto.

Salida (structuredContent y cuerpo de la REST)

CampoTipoDescripción
contratostringVersión del contrato con que se produjo la respuesta.
Valores: luthor-datos/1.
resultadosarrayNormas en orden de posicion, sin extracto. Una búsqueda sin resultados devuelve la lista vacía y sí se cobra.
≤ 10 elementos.
resultados[].idstringIdentificador de la norma (ORD-{id}): la ÚNICA identidad (hay títulos homónimos). Úsalo para leerla.
patrón ^ORD-(?:0|[1-9][0-9]{0,11})$.
resultados[].familiastringordenamiento.
Valores: ordenamiento.
resultados[].urlstring | nullPágina pública de la norma (o de la versión leída) en luthor.mx.
≤ 256 caracteres; patrón ^https://luthor\.mx/.
resultados[].procedenciaobjectDe dónde sale la norma. La fuente es siempre «Archivo Soberano Luthor».
resultados[].procedencia.fuentestringAtribución obligatoria: «Archivo Soberano Luthor».
Valores: Archivo Soberano Luthor.
resultados[].procedencia.revisionstring | nullLa versión leída (su reforma_id) o, en una búsqueda, null.
≤ 128 caracteres.
resultados[].procedencia.fecha_revisionstring | nullFecha de publicación de la versión leída, o null.
patrón ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$.
resultados[].procedencia.ambitostringfederal, estatal o tratados (internacionales).
Valores: federal, estatal, tratados.
resultados[].procedencia.entidadstring | nullLa entidad federativa de una norma estatal; null en federal y tratados.
resultados[].procedencia.categoriastring | nullLa categoría tal como la trae el catálogo (LEY, REGLAMENTO, CODIGO…), o null.
≤ 64 caracteres.
resultados[].titulostringTítulo de la norma, como lo trae el catálogo.
resultados[].vigencia_ordenamientoobjectQué se puede afirmar de la vigencia de la NORMA completa, con su fuente y su fecha de corte. No se refiere a un artículo.
resultados[].vigencia_ordenamiento.estadostringvigente, no_vigente, abrogado, derogado, sin_efecto, indeterminado (dos evidencias que chocan) o desconocido. «vigente» siempre con fuente y fecha de corte.
Valores: vigente, no_vigente, abrogado, derogado, sin_efecto, indeterminado, desconocido.
resultados[].vigencia_ordenamiento.fuentestringDe dónde sale el estado: catalogo_del_archivo (la etiqueta del catálogo del Archivo Soberano Luthor a su fecha de corte), regla_ejercicio (una ley de ingresos o un presupuesto de un ejercicio concluido) o abrogacion_con_cita (una norma posterior que la abroga, citada).
Valores: catalogo_del_archivo, regla_ejercicio, abrogacion_con_cita.
resultados[].vigencia_ordenamiento.fecha_cortestring | nullFecha de negocio (AAAA-MM-DD) de la evidencia (hoy, el censo del catálogo); null si no la hay.
patrón ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$.
resultados[].vigencia_ordenamiento.fecha_efectostring | nullFecha de negocio (AAAA-MM-DD) en que el estado surtió efecto, o null si no se conoce.
patrón ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$.
resultados[].vigencia_ordenamiento.confianzastringalta = verificada; media o baja = registrada, no verificada.
Valores: alta, media, baja.
resultados[].vigencia_ordenamiento.etiqueta_archivostring | nullLa etiqueta de vigencia tal como la trae el catálogo, por transparencia, o null.
≤ 64 caracteres.
resultados[].version_vigenteobject | nullLa versión que rige hoy según el catálogo, con el texto que tiene; null si el catálogo no la determina.
resultados[].version_vigente.reforma_idstringIdentificador de la versión (úsalo en ORD-{id}@{reforma_id}).
patrón ^(?:0|[1-9][0-9]{0,11})$.
resultados[].version_vigente.fecha_publicacionstring | nullFecha de publicación de la versión (AAAA-MM-DD), o null.
patrón ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$.
resultados[].version_vigente.reglastringCómo se eligió: censo (el puntero del catálogo del archivo) o fecha_v1 (la última publicada con fecha hasta hoy).
Valores: censo, fecha_v1.
resultados[].version_vigente.confianzastringalta = verificada; media o baja = registrada, no verificada.
Valores: alta, media, baja.
resultados[].version_vigente.textostringQué texto tiene esa versión: articulado (legible), facsimil (sólo imagen: no se puede leer) o sin_texto.
Valores: articulado, facsimil, sin_texto.
resultados[].version_vigente.ultima_con_articuladoobjectOpcional: la última versión con articulado legible, cuando la vigente no lo tiene.
resultados[].version_vigente.ultima_con_articulado.reforma_idstringIdentificador de esa versión.
patrón ^(?:0|[1-9][0-9]{0,11})$.
resultados[].version_vigente.ultima_con_articulado.fecha_publicacionstring | nullSu fecha de publicación, o null.
patrón ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$.
resultados[].version_vigente.proximaobjectOpcional: una versión publicada que aún no entra en vigor.
resultados[].version_vigente.proxima.reforma_idstringIdentificador de esa versión.
patrón ^(?:0|[1-9][0-9]{0,11})$.
resultados[].version_vigente.proxima.entrada_en_vigorstringFecha en que entra en vigor (AAAA-MM-DD).
patrón ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$.
resultados[].version_vigente.empatearrayOpcional: otras versiones publicadas el mismo día que la vigente.
≤ 20 elementos.
resultados[].texto_transformadobooleantrue si el saneador modificó el texto servido.
resultados[].posicionintegerLugar en la lista, desde 1.
de 1 a 10.
resultados[].puntajenumberPuntaje del criterio de ranking. Sólo compara resultados de la misma respuesta.
resultados[].criterio_rankingstringlexico_catalogo: coincidencia de palabras en la ficha del catálogo; el puntaje es 1/posición y sólo ordena.
Valores: lexico_catalogo.
modo_efectivostringrapida: la búsqueda de normas no usa modelos de lenguaje.
Valores: rapida.
truncadoobjectSi la lista se recortó para caber en el techo de salida.
truncado.truncadobooleantrue si se entregaron menos resultados, o extractos más cortos, de los que había.
Valores: false, true.
truncado.motivostring | nullPor qué se recortó; null si no se recortó.
Valores: TECHO_DE_SALIDA.
truncado.resultados_entregadosintegerCuántos resultados trae la respuesta.
de 0 a 10.
truncado.resultados_candidatosintegerCuántos había antes del recorte.
≥ 0.
truncado.extracto_max_caracteresintegerLargo máximo que se usó para los extractos de esta respuesta.
de 0 a 1,200.
corpusobjectQué colección sirvió la respuesta y de qué fecha es.
corpus.coleccionstringarchivo: la normativa del Archivo Soberano Luthor.
Valores: curado, archivo.
corpus.cortestring | nullFecha de negocio (AAAA-MM-DD) del catálogo de la normativa (su censo), o null.
patrón ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$.
corpus.revisionstring | nullIdentificador de la revisión del catálogo, o null.
≤ 128 caracteres.

Leer ordenamiento — luthor_leer_ordenamiento

Lee el texto de una norma del Archivo Soberano Luthor por su identificador (ORD-… de luthor_buscar_ordenamiento): todo su articulado por fragmentos fijos, un artículo por su número o los artículos que tratan un tema. Úsala cuando ya tengas el identificador de la norma y necesites su texto para citarla o analizarla. Devuelve el texto de la versión vigente, o de la versión pedida, como transcripción sin cotejar de la versión publicada, con su procedencia, la vigencia declarada y el truncado declarado; si esa versión sólo existe como facsímil, responde SIN_TEXTO_LEGIBLE y no hay texto que citar.

REST: GET /v1/ordenamientos/{id} (con ?fragmento=N y ?articulo= o ?consulta= opcionales; el id va sólo en la ruta). MCP: tool luthor_leer_ordenamiento. Cobro: 1 unidad por fragmento entregado.

Se pide con articulo o con consulta, nunca con los dos; sin ninguno, se lee todo el articulado por fragmentos. Si la versión sólo existe como facsímil, responde SIN_TEXTO_LEGIBLE (sin cobro): no hay texto que citar.

Entrada

CampoTipoObligatorioDescripción
idstringsíIdentificador de la norma, p. ej. ORD-160795 (su versión vigente), o de una versión, p. ej. ORD-160795@3, tal como lo devuelve luthor_buscar_ordenamiento.
patrón ^ORD-(?:0|[1-9][0-9]{0,11})(?:@(?:0|[1-9][0-9]{0,11}))?$.
articulostringnoNúmero de un artículo de la norma, p. ej. 5, 5-A o PRIMERO. Va sin consulta.
de 1 a 40 caracteres; patrón ^[0-9A-Za-zÁÉÍÓÚÑáéíóúñ][0-9A-Za-zÁÉÍÓÚÑáéíóúñ .-]*$.
consultastringnoTema a localizar dentro de la norma: entrega hasta 5 artículos que hablan de él, en orden de relevancia. Va sin articulo.
de 1 a 200 caracteres.
fragmentointegernoFragmento del documento, base 1. Los fragmentos son fijos por documento; cada uno es una lectura.
de 1 a 100,000. Por omisión: 1.

Salida (structuredContent y cuerpo de la REST)

CampoTipoDescripción
contratostringVersión del contrato con que se produjo la respuesta.
Valores: luthor-datos/1.
documentoobjectLa norma leída, con su sobre.
documento.idstringLa versión leída (ORD-{id}@{rid}): úsalo para pedir los demás fragmentos de la MISMA versión.
patrón ^ORD-(?:0|[1-9][0-9]{0,11})@(?:0|[1-9][0-9]{0,11})$.
documento.familiastringordenamiento.
Valores: ordenamiento.
documento.urlstring | nullPágina pública de la norma (o de la versión leída) en luthor.mx.
≤ 256 caracteres; patrón ^https://luthor\.mx/.
documento.procedenciaobjectDe dónde sale la norma. La fuente es siempre «Archivo Soberano Luthor».
documento.procedencia.fuentestringAtribución obligatoria: «Archivo Soberano Luthor».
Valores: Archivo Soberano Luthor.
documento.procedencia.revisionstring | nullLa versión leída (su reforma_id) o, en una búsqueda, null.
≤ 128 caracteres.
documento.procedencia.fecha_revisionstring | nullFecha de publicación de la versión leída, o null.
patrón ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$.
documento.procedencia.ambitostringfederal, estatal o tratados (internacionales).
Valores: federal, estatal, tratados.
documento.procedencia.entidadstring | nullLa entidad federativa de una norma estatal; null en federal y tratados.
documento.procedencia.categoriastring | nullLa categoría tal como la trae el catálogo (LEY, REGLAMENTO, CODIGO…), o null.
≤ 64 caracteres.
documento.titulostringTítulo de la norma, como lo trae el catálogo.
documento.vigencia_ordenamientoobjectQué se puede afirmar de la vigencia de la NORMA completa, con su fuente y su fecha de corte. No se refiere a un artículo.
documento.vigencia_ordenamiento.estadostringvigente, no_vigente, abrogado, derogado, sin_efecto, indeterminado (dos evidencias que chocan) o desconocido. «vigente» siempre con fuente y fecha de corte.
Valores: vigente, no_vigente, abrogado, derogado, sin_efecto, indeterminado, desconocido.
documento.vigencia_ordenamiento.fuentestringDe dónde sale el estado: catalogo_del_archivo (la etiqueta del catálogo del Archivo Soberano Luthor a su fecha de corte), regla_ejercicio (una ley de ingresos o un presupuesto de un ejercicio concluido) o abrogacion_con_cita (una norma posterior que la abroga, citada).
Valores: catalogo_del_archivo, regla_ejercicio, abrogacion_con_cita.
documento.vigencia_ordenamiento.fecha_cortestring | nullFecha de negocio (AAAA-MM-DD) de la evidencia (hoy, el censo del catálogo); null si no la hay.
patrón ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$.
documento.vigencia_ordenamiento.fecha_efectostring | nullFecha de negocio (AAAA-MM-DD) en que el estado surtió efecto, o null si no se conoce.
patrón ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$.
documento.vigencia_ordenamiento.confianzastringalta = verificada; media o baja = registrada, no verificada.
Valores: alta, media, baja.
documento.vigencia_ordenamiento.etiqueta_archivostring | nullLa etiqueta de vigencia tal como la trae el catálogo, por transparencia, o null.
≤ 64 caracteres.
documento.version_vigenteobject | nullLa versión que rige hoy según el catálogo, con el texto que tiene; null si el catálogo no la determina.
documento.version_vigente.reforma_idstringIdentificador de la versión (úsalo en ORD-{id}@{reforma_id}).
patrón ^(?:0|[1-9][0-9]{0,11})$.
documento.version_vigente.fecha_publicacionstring | nullFecha de publicación de la versión (AAAA-MM-DD), o null.
patrón ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$.
documento.version_vigente.reglastringCómo se eligió: censo (el puntero del catálogo del archivo) o fecha_v1 (la última publicada con fecha hasta hoy).
Valores: censo, fecha_v1.
documento.version_vigente.confianzastringalta = verificada; media o baja = registrada, no verificada.
Valores: alta, media, baja.
documento.version_vigente.textostringQué texto tiene esa versión: articulado (legible), facsimil (sólo imagen: no se puede leer) o sin_texto.
Valores: articulado, facsimil, sin_texto.
documento.version_vigente.ultima_con_articuladoobjectOpcional: la última versión con articulado legible, cuando la vigente no lo tiene.
documento.version_vigente.ultima_con_articulado.reforma_idstringIdentificador de esa versión.
patrón ^(?:0|[1-9][0-9]{0,11})$.
documento.version_vigente.ultima_con_articulado.fecha_publicacionstring | nullSu fecha de publicación, o null.
patrón ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$.
documento.version_vigente.proximaobjectOpcional: una versión publicada que aún no entra en vigor.
documento.version_vigente.proxima.reforma_idstringIdentificador de esa versión.
patrón ^(?:0|[1-9][0-9]{0,11})$.
documento.version_vigente.proxima.entrada_en_vigorstringFecha en que entra en vigor (AAAA-MM-DD).
patrón ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$.
documento.version_vigente.empatearrayOpcional: otras versiones publicadas el mismo día que la vigente.
≤ 20 elementos.
documento.texto_transformadobooleantrue si el saneador modificó el texto servido.
documento.lecturaobjectQué entregó la lectura.
documento.lectura.alcancestringarticulado (toda la norma), articulo (uno) o consulta (los que tratan el tema pedido).
Valores: articulado, articulo, consulta.
documento.lectura.articulosarrayLos artículos entregados (vacío al leer el articulado completo).
≤ 5 elementos.
documento.lectura.articulos[].numerostringNúmero del artículo, como lo trae la norma.
de 1 a 64 caracteres.
documento.lectura.articulos[].urlstring | nullSu URL en luthor.mx, o null.
≤ 256 caracteres; patrón ^https://luthor\.mx/.
documento.textostringTexto del fragmento pedido, saneado. Concatenar todos los fragmentos da el texto completo.
documento.truncadoobjectSi el documento se entregó por fragmentos.
documento.truncado.truncadobooleantrue si el documento tiene más de un fragmento.
Valores: false, true.
documento.truncado.motivostring | nullFRAGMENTADO si tiene más de un fragmento; si no, null.
Valores: FRAGMENTADO.
documento.truncado.fragmentointegerFragmento entregado (base 1); null en un extracto.
Valores: 1. ≥ 1.
documento.truncado.fragmentos_totalesintegerCuántos fragmentos tiene el documento; null en un extracto.
Valores: 1. ≥ 2.
documento.truncado.bytes_entregadosintegerBytes UTF-8 del texto entregado.
≥ 0.
documento.truncado.bytes_totalesintegerBytes UTF-8 del texto completo.
≥ 0.
corpusobjectQué colección sirvió la respuesta y de qué fecha es.
corpus.coleccionstringarchivo: la normativa del Archivo Soberano Luthor.
Valores: curado, archivo.
corpus.cortestring | nullFecha de negocio (AAAA-MM-DD) del catálogo de la normativa (su censo), o null.
patrón ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$.
corpus.revisionstring | nullIdentificador de la revisión del catálogo, o null.
≤ 128 caracteres.

Errores y qué hacer

Ningún error cobra. Por REST llegan como application/problem+json; por MCP, los de validación y negocio vuelven como resultado de tool con isError:true para que el modelo corrija su llamada, y el único error de protocolo es una tool desconocida o un mensaje mal formado. Un 429 o un 503 traen Retry-After. Ningún error lleva tu consulta, el texto de un documento ni tu llave.

CódigoHTTP (REST)MCPQué pasóQué hacer
ARGUMENTO_INVALIDO422resultado de tool con isError:trueUn argumento no cumple el esquema de la operación.Corrige el argumento indicado en campo y vuelve a llamar.
ID_INVALIDO422resultado de tool con isError:trueEl identificador no tiene un formato válido.Usa un identificador devuelto por la búsqueda de la misma familia.
LEY_FUERA_DE_CATALOGO422resultado de tool con isError:trueLa ley no está en el catálogo de 16 ordenamientos del corpus curado.Usa uno de los códigos de ley del catálogo (p. ej. CFF, LISR, LIVA).
FRAGMENTO_FUERA_DE_RANGO422resultado de tool con isError:trueEl documento no tiene ese fragmento.Pide un fragmento entre 1 y fragmentos_totales.
TECHO_INSUFICIENTE422resultado de tool con isError:trueEl resultado mínimo útil no cabe en el techo de salida.Pide un techo de salida mayor, hasta el máximo contractual.
NO_ENCONTRADO404resultado de tool con isError:trueNo hay un documento con ese identificador en lo que sirve esta API.Busca primero y usa un identificador de los resultados.
DEROGADO410resultado de tool con isError:trueEl artículo está derogado: su texto servido es la derogación.Busca el artículo vigente que regula la materia.
NO_MIGRADO404resultado de tool con isError:trueEl documento existe en el Archivo Soberano Luthor pero no forma parte del corpus curado que sirve esta versión.Busca en el corpus curado un documento equivalente.
SIN_TEXTO_LEGIBLE404resultado de tool con isError:trueLa norma existe en el Archivo Soberano Luthor, pero esa versión no tiene texto legible: sólo un facsímil o ningún texto.No reconstruyas el texto ni lo cites de memoria: nombra la norma por su título y su URL, donde está el facsímil si existe.
CUOTA_AGOTADA402resultado de tool con isError:trueLa cuota del periodo está agotada y el excedente no está permitido.El administrador de la organización puede permitir excedente en el portal; la cuota reinicia el primer día del mes (hora de CDMX).
TOPE_ALCANZADO402resultado de tool con isError:trueLa organización alcanzó su tope de gasto del mes.El administrador de la organización puede subir el tope en el portal; reinicia el primer día del mes (hora de CDMX).
COBERTURA_AGOTADA402resultado de tool con isError:trueLa organización alcanzó el techo de documentos distintos de su plan en 30 días.Para volúmenes mayores, el plan Datos incluye entregas en bloque.
LIMITE_DIARIO429resultado de tool con isError:trueSe alcanzó el límite de llamadas del día.El límite se renueva a las 00:00 (hora de CDMX); reintenta después de los segundos indicados.
ORG_SUSPENDIDA403resultado de tool con isError:trueLa organización está suspendida.El administrador de la organización debe contactar a soporte.
LLAVE_AUSENTE401HTTP antes de ejecutarFalta la llave de la organización.Envía Authorization: Bearer <llave>.
LLAVE_INVALIDA401HTTP antes de ejecutarLa llave no es válida o fue revocada.Usa una llave vigente de tu organización.
ENTORNO_CRUZADO403HTTP antes de ejecutarLa llave no corresponde a este entorno.Usa una llave test en el sandbox y una live en producción.
SCOPE_INSUFICIENTE403HTTP antes de ejecutarLa llave no tiene permiso para esta operación.El administrador de la organización puede crear una llave con el permiso necesario.
RAFAGA_EXCEDIDA429HTTP antes de ejecutarDemasiadas llamadas en poco tiempo.Espera los segundos indicados y reintenta.
IDEMPOTENCIA_EN_CONFLICTO409HTTP antes de ejecutarLa Idempotency-Key ya se usó con otra solicitud o agotó sus repeticiones.Usa una Idempotency-Key nueva para cada solicitud distinta.
IDEMPOTENCIA_EN_CURSO409HTTP antes de ejecutarUna solicitud con esta Idempotency-Key sigue en curso.Espera los segundos indicados y repite la misma solicitud.
TEMPORALMENTE_NO_DISPONIBLE503resultado de tool con isError:trueUna dependencia del servicio no respondió.Reintenta en unos segundos; no se cobró la llamada.
ERROR_INTERNO500resultado de tool con isError:trueEl servicio no pudo producir un resultado válido.Reintenta; si persiste, escribe a soporte. No se cobró la llamada.
HERRAMIENTA_DESCONOCIDA404error JSON-RPCLa operación no existe.Usa una de las cuatro operaciones publicadas.
SOLICITUD_MALFORMADA400error JSON-RPCLa solicitud no es JSON válido.Envía un cuerpo JSON bien formado.

Forma del error

CampoTipoDescripción
codigostringCódigo del catálogo de errores (ver Errores).
mensajestringQué pasó, en español. Nunca trae tu consulta ni el texto de un documento.
de 1 a 400 caracteres.
accionstringQué hacer para resolverlo.
de 1 a 400 caracteres.
campostring | nullEl argumento que falló (sólo validación), nunca su valor; null en otros errores.
≤ 120 caracteres.
fragmentos_totalesinteger | nullSólo FRAGMENTO_FUERA_DE_RANGO: cuántos fragmentos tiene el documento.
≥ 1.
reintentar_en_sinteger | nullSólo 429, 503 y IDEMPOTENCIA_EN_CURSO: segundos antes de reintentar.
≥ 0.

Límites

LímiteValor
Techo de salida por omisión10,000 tokens por resultado serializado completo (se mide con la cota tokens ≤ bytes UTF-8 e incluye el bloque de texto que repite el JSON).
Máximo contractual64 KiB UTF-8 y 16,000 tokens. Hoy la puerta entrega el techo por omisión.
ConsultaDe 1 a 4,000 caracteres; en la búsqueda completa de tesis, hasta 1,000.
Resultados por búsquedaDe 1 a 10 (5 por omisión). Extractos de hasta 1,200 caracteres; si no caben en el techo, se entregan menos o más cortos, y se declara.
Fragmentos de lecturaFijos por documento (≈ 2,250 B de texto cada uno). Cada fragmento es una lectura.
EntradaJSON de hasta 32 KiB; el cuerpo HTTP, hasta 64 KiB.
Tiempo máximo por operación30 s; si se agota, 503 sin cobro.
Ráfaga por llave (provisional)Developer 30 y Growth 100 llamadas cada 10 s; por organización, 60 y 300. Nunca por IP.
Llamadas en curso por organización (provisional)Developer 8 · Growth 32.
Idempotency-Key (sólo REST)Misma clave y mismo cuerpo dentro de 24 h devuelven el mismo evento sin segundo cobro, hasta 3 repeticiones. Por MCP cada llamada es nueva y cobra.

Unidades y precios

Precios en MXN más IVA. La cuota es una bolsa de unidades por mes (hora de CDMX): una lectura = 1 unidad por fragmento, una búsqueda rápida = 5 y una búsqueda completa de tesis = 20. Una búsqueda sin resultados sí se cobra. Un error nunca.

PlanPrecioIncluyeExcedente
SandboxGratisLlaves test, corpus fijo, 100 llamadas por día, sin acuerdo de nivel de servicio.No aplica.
Developer$1,990 al mes20,000 unidades: 20,000 lecturas, o 4,000 búsquedas rápidas, o 1,000 completas.$0.20 lectura · $1.00 búsqueda rápida · $2.50 búsqueda completa.
GrowthDesde $19,900 al mes200,000 unidades; compromiso trimestral; soporte en un día hábil; avisos de cambio.El mismo esquema.
Enterprise / DatosDesde US$2,500 al mesContrato anual y entregas en bloque.Por contrato.

Cada organización fija un tope de gasto mensual en excedente (por omisión, igual a la cuota base). Al alcanzarlo, las llamadas se rechazan sin cobro hasta el mes siguiente o hasta que el administrador lo suba. Cada respuesta REST exitosa trae la cabecera Luthor-Unidades con lo cobrado (un error no cobra y no la trae). Facturación mensual por transferencia contra CFDI.

Corpus y cobertura

Tesis: el Archivo Soberano Luthor, 311,972 tesis del Poder Judicial de la Federación en la búsqueda rápida y en la completa (sin filtro de época se busca de la Novena a la Duodécima, y el Tribunal Electoral; la Quinta a la Octava, con el filtro epoca); la búsqueda completa suma además las 48,242 del Tribunal Federal de Justicia Administrativa, que se cuentan aparte, se entregan después de las del Poder Judicial y llevan su peso. Leyes: 16 (CFF, LISR, LIVA, LFPCA, RCFF, RLISR, RLIVA, RMF-2026, LAMP, LOTFJA, CPEUM, RISAT, LFT, CNPP, CPF, CCOM), 5,880 artículos. Cada respuesta declara su corpus.corte: la fecha de la última publicación de esa familia o el corte del archivo. No se promete frescura; revisa esa fecha.

Techo de cobertura: además de la cuota, cada plan tiene un máximo de documentos distintos leídos en 30 días móviles: Developer 4,000 y Growth 15,000. Releer un documento no cuenta dos veces. Rebasarlo es COBERTURA_AGOTADA; para volúmenes mayores está el plan Datos. Los términos prohíben reconstruir el corpus, revenderlo o entrenar modelos sin licencia de Datos.

Normativa: además de las 16 leyes, la normativa del Archivo Soberano Luthor —federal, de las 32 entidades federativas y los tratados internacionales— con luthor_buscar_ordenamiento y luthor_leer_ordenamiento. Cada norma trae su vigencia_ordenamiento declarada (con su fuente, su fecha de corte y su confianza: la del catálogo es registrada, no verificada) y su version_vigente, con el tipo de texto que tiene. Muchas normas estatales sólo existen como facsímil (imagen): su lectura es SIN_TEXTO_LEGIBLE y su texto nunca se reconstruye.

Atribución: la fuente que debes citar es «Archivo Soberano Luthor». Cada documento trae su procedencia (órgano, clave, registro, época y localización en tesis; ley y número en artículos; ámbito, entidad y categoría en la normativa).

Sandbox

Endpoint: https://sandbox.luthor.mx/mcp y https://sandbox.luthor.mx/v1/…. Llaves lxk_test_. Gratis, 100 llamadas por día (hora de CDMX), sin acuerdo de nivel de servicio. Una llave test contra producción, o una live contra el sandbox, recibe 403.

El sandbox responde desde un corpus fijo: CFF y LIVA completos y 1,000 tesis. Las respuestas las genera de antemano el mismo código del servicio, sobre ese subconjunto reconstruido de las fuentes del corpus: tienen el mismo contrato, los mismos errores y las mismas unidades. Diferencias que conviene conocer:

Consultas de tesis (rápida y completa)

Consultas de artículos (sin ley, o con ley CFF o LIVA)

Normativa del archivo (12 normas fijas)

Cuatro federales, cuatro tratados y cuatro estatales, con una que sólo existe como facsímil (su lectura es SIN_TEXTO_LEGIBLE), una abrogada y su homónima vigente. Se leen por su id (su articulado completo, su versión vigente explícita y cada artículo por su número) y con la consulta indicada; otra lectura es NO_ENCONTRADO.

Consultas de normas (sin filtros)

Estado del servicio

Sondas sintéticas con hora de CDMX: https://mcp.luthor.mx/status (también en JSON: https://mcp.luthor.mx/status.json, con la fuente de cada componente). Las cuatro operaciones de tesis y artículos se sondean contra el sandbox, que no pasa por la búsqueda semántica ni por modelos de lenguaje, y un componente aparte mide el almacenamiento del servicio. No miden el camino de producción completo: una falla ahí se publica en la misma página como incidente.

Versiones y deprecación

La REST se versiona por ruta (/v1/) y las tools por nombre estable. Un cambio compatible agrega un campo opcional. Un cambio incompatible es una operación nueva o una versión nueva del contrato, con aviso de 90 días antes de retirar la anterior; la fecha de retiro se publica aquí y en el _meta de la tool que se retira.

Cambios

FechaContratoTipoCambio
2026-09-29luthor-datos/1.3compatibleRevisión 1.3, ampliación aditiva: dos herramientas NUEVAS y ningún cambio en las cuatro de siempre (sus salidas son las de la 1.2, byte a byte). luthor_buscar_ordenamiento busca normas de la normativa del Archivo Soberano Luthor —federales, de las 32 entidades federativas y tratados internacionales— por palabras de su ficha, con filtros de ámbito, entidad, categoría y vigencia; luthor_leer_ordenamiento lee su texto por fragmentos fijos: todo el articulado, un artículo por su número o los artículos que tratan un tema. La identidad de una norma es ORD-{id} (hay títulos homónimos) y la de una versión, ORD-{id}@{rid}. Cada norma trae vigencia_ordenamiento (estado, fuente, fecha de corte, fecha de efecto, confianza y la etiqueta del catálogo; la del catálogo es registrada, no verificada) y version_vigente (la versión que rige según el catálogo y el tipo de texto que tiene). Error nuevo SIN_TEXTO_LEGIBLE (404, sin cobro): la norma existe pero esa versión sólo es un facsímil o no tiene texto; su texto no se reconstruye. Cobro: la búsqueda es una búsqueda rápida y la lectura, una unidad por fragmento; usan los permisos de artículos (articulos:buscar y articulos:leer). En REST: POST /v1/ordenamientos/buscar y GET /v1/ordenamientos/{id}. Un cliente MCP las ve al volver a listar las herramientas (en Claude, una conversación nueva).
2026-09-29luthor-datos/1.2compatibleRevisión 1.2, ampliación aditiva: no se quita ni se renombra nada, pero sí cambian dominios. Las tesis se buscan y se leen en el Archivo Soberano Luthor completo (311,972 del Poder Judicial de la Federación) y no sólo en el corpus curado; la búsqueda completa suma las 48,242 del Tribunal Federal de Justicia Administrativa, que se cuentan aparte y se entregan después de las del Poder Judicial. Entrada: identificadores TFJA-n en luthor_leer_tesis, el tipo «precedente» y las épocas de la Quinta a la Novena en los filtros. Salida: corpus.coleccion deja de ser una constante («curado») y pasa a un enumerado que agrega «archivo»; id admite TFJA-n; estado_tesis.tipo admite «precedente»; criterio_ranking admite «hibrido» (búsqueda semántica y por palabras fundidas por rango: su puntaje sólo ordena). Campos nuevos y OPCIONALES por tesis: coleccion, peso (a quién obliga una tesis del Tribunal Federal de Justicia Administrativa, con su artículo) y situacion (lo que el archivo registra de la tesis). Un cliente que valida la salida con el esquema anterior en modo estricto debe descargar el esquema nuevo. La identidad de una tesis es su id (JP-n o TFJA-n), no procedencia.registro: una del Tribunal Federal de Justicia Administrativa y una del Poder Judicial pueden compartir número. Una tesis del archivo que no estaba en el curado ya se lee (antes, NO_MIGRADO). El campo contrato de cada respuesta sigue diciendo «luthor-datos/1». Desde esta revisión, el outputSchema que anuncia el MCP (tools/list) es la versión TOLERANTE del esquema de salida: la misma forma (tipos, campos y requeridos) sin objetos cerrados ni listas cerradas de valores, así que un cliente que lo guardó acepta los campos y valores que se agreguen después. El esquema estricto sigue en la documentación y en la REST, y el servidor valida cada respuesta con él. Un cliente MCP que guardó el esquema de la 1.0 o de la 1.1 debe volver a listar las herramientas (en Claude, abrir una conversación nueva).
2026-09-29luthor-datos/1.1compatibleRevisión 1.1, ampliación aditiva: no se quita ni se renombra nada. La vigencia de un artículo puede ser «vigente» con la fuente nueva cotejo_con_archivo: su texto es idéntico al del mismo artículo en la última versión del ordenamiento en el Archivo Soberano Luthor, no hay una reforma posterior registrada y la última revisión de reformas de la ley es reciente (fecha_corte es su día). Causas nuevas de NO_VERIFICADO: DIFIERE_DEL_ARCHIVO (el texto no es idéntico al de la versión cotejada) y COTEJO_DESACTUALIZADO (no hay una revisión reciente de reformas, o se registró una reforma posterior a la versión cotejada). Al leer el artículo (luthor_leer_articulo), con cotejo_con_archivo vienen dos campos obligatorios: ultima_reforma (la fecha de la última reforma, adición o derogación que esa versión registra para el artículo; null si no registra ninguna) y version_cotejada (la fecha de publicación de la versión), que también acompaña a DIFIERE_DEL_ARCHIVO y a COTEJO_DESACTUALIZADO cuando se conoce. En la búsqueda (luthor_buscar_articulo) la vigencia viaja compacta, con los cinco campos de siempre y sin esos dos, para que el techo de salida no cueste resultados: para verlos, lee el artículo. El campo contrato de cada respuesta sigue diciendo «luthor-datos/1». Para un cliente MCP que valida con el esquema estricto que guardó (el de la 1.0), la fuente y los campos nuevos no son aditivos: ver la 1.2, que anuncia el esquema tolerante.
2026-09-28luthor-datos/1compatibleNuevo código de error LIMITE_DIARIO: el tope de llamadas por día (hora de CDMX) de los planes que lo tienen. En la REST es un 429 con Retry-After hasta las 00:00 de CDMX; en el MCP, un resultado de herramienta con isError, para que el modelo lea el mensaje. Es distinto de RAFAGA_EXCEDIDA (segundos) y de CUOTA_AGOTADA (el mes). Los planes de organización vigentes no tienen tope diario.
2026-09-28luthor-datos/1compatibleLa raíz del esquema de entrada de luthor_leer_articulo es ahora un objeto plano, sin oneOf: algunos clientes, como la Messages API de Anthropic, rechazan combinadores en la raíz de un inputSchema. La regla no cambia (id, o bien ley y articulo, pero no ambos): la declaran las descripciones y la exige el servidor, con el mismo código, campo y mensaje de error. Las cuatro herramientas dicen además cuándo usarlas. El endpoint MCP responde 403 a toda petición que traiga la cabecera Origin (antes aceptaba las de localhost): sus clientes son de servidor y no la mandan.
2026-09-24luthor-datos/1nuevoPrimera versión del contrato: cuatro operaciones (buscar y leer tesis, buscar y leer artículos) por REST y por MCP, llaves por organización, sandbox con corpus fijo, docs y página de estado.

Soporte

Un solo canal: jccc@bytx.dev. Growth: respuesta en un día hábil.

La información que entrega esta API es de consulta. No constituye asesoría jurídica ni sustituye la revisión de un profesional del derecho.