Skip to main content
Glama
osha-recordkeeping-mcp

osha-recordkeeping-mcp

by srhtdmrkl

OSHA Recordkeeping MCP — 29 CFR Part 1904

Un servidor determinista del Model Context Protocol que ayuda a un gerente de seguridad a responder la pregunta que enfrenta cada vez que alguien resulta herido: ¿es esto registrable según OSHA?

Once herramientas siguen un incidente desde alguien resultó herido hasta una entrada de registro correcta, cada una devuelve una determinación citada en lugar del recuerdo del modelo sobre la regla. Licencia MIT y uso gratuito.

Solo referencia y triaje: no es asesoramiento legal ni una determinación médica. Cada determinación incluye su cita del CFR y la fecha en que los datos subyacentes se verificaron por última vez contra eCFR, de modo que el razonamiento es auditable en lugar de afirmado.

Cómo usarlo

git clone https://github.com/srhtdmrkl/osha-recordkeeping-mcp.git
cd osha-recordkeeping-mcp && npm install && npm run build

Luego añádelo al claude_desktop_config.json de Claude Desktop:

{
  "mcpServers": {
    "osha": { "command": "node", "args": ["/absolute/path/to/dist/index.js"] }
  }
}

Usa una ruta absoluta a tu binario node si usas nvm: Claude Desktop no carga tu perfil de shell, por lo que un node simple no se resolverá.

El Skill complementario contiene el procedimiento: cuándo se aplica la cadena, qué establecer antes de llamar y qué no pueden decidir las herramientas.

Related MCP server: stcc-mcp

Por qué existe esta herramienta

La evaluación de la registrabilidad de lesiones laborales según 29 CFR Part 1904 ocurre en cada incidente. Las determinaciones incorrectas conllevan riesgos directos de cumplimiento: el sobre-registro infla artificialmente la Tasa de Incidentes Registrables Totales (TRIR), mientras que el sub-registro conlleva citaciones de OSHA según 29 CFR 1904.4.

La registrabilidad según la Parte 1904 evalúa múltiples desencadenantes independientes: criterios generales (muerte, días de ausencia, restricción laboral, pérdida de conciencia, diagnósticos de PLHCP según 1904.7), reglas de casos específicos (pinchazos con aguja, retiro médico, pérdida auditiva, TB según 1904.8–1904.12) y clasificación del tratamiento. Para el tratamiento, 1904.7(b)(5)(ii) define una lista cerrada y enumerada de 14 elementos de tratamientos de primeros auxilios. Implementar estas reglas regulatorias cerradas dentro de herramientas tipadas reemplaza la interpolación del LLM sobre el texto regulatorio con lógica de búsqueda reproducible.

División del trabajo: el LLM narra, la herramienta decide

El modelo que llama hace lo que se le da bien: leer una narrativa de incidente desordenada y mapearla a códigos canónicos (tipos de tratamiento, resultados). La herramienta hace lo que un modelo no debe hacer para una determinación legal: aplicar la lista cerrada de forma determinista y devolver una respuesta citada. La herramienta nunca acepta descripciones de tratamiento en texto libre; acepta un vocabulario controlado para que la determinación sea reproducible.

La herramienta ancla: osha_assess_recordability

Entrada. El modelo mapea la narrativa a estos campos; nunca pasa texto libre.

Campo

Significado

work_related

1904.5 — proporcionar desde osha_assess_work_relatedness, no juzgarlo aquí

new_case

1904.6 — proporcionar desde osha_assess_new_case

outcomes

death, days_away_from_work, restricted_work_or_transfer, loss_of_consciousness

significant_diagnoses

cancer, chronic_irreversible_disease, fractured_or_cracked_bone, punctured_eardrum (1904.7(b)(7))

specific_case_criteria

Desencadenantes de 1904.8-1904.12: pinchazo con aguja, retiro médico, pérdida auditiva, TB, exposición a patógenos sanguíneos con diagnóstico

plhcp_recommendations_not_followed

Los tres casos en que una recomendación vincula incluso cuando el empleado la ignoró (1904.7(b)(3)(ii), (b)(4)(viii), (b)(5)(v))

medical_removal_was_voluntary_and_early

Protección para 1904.9(b)(3): retirar a alguien temprano no es registrable

tuberculosis_test_was_pre_employment

Protección para 1904.11(b)(1): un positivo en el examen físico de contratación no es ocupacional

treatments

Códigos controlados. Los códigos de primeros auxilios provienen de la lista cerrada; dos códigos no son ni primeros auxilios ni tratamiento médico (1904.7(b)(5)(i))

Los primeros tres arreglos son obligatorios, deliberadamente. Un valor predeterminado de [] no se puede distinguir de "verifiqué y no había ninguno", por lo que establecerlos por defecto permite que una narrativa insuficientemente especificada devuelva un falso negativo seguro y citado, la dirección de sub-registro que atrae una citación.

Salida. Un RuleRecord cuyo valor incluye recordable, basis, triggering_factors (cada uno con su propia cita de subcláusula), severe_injury_reporting_note cuando 1904.39 puede estar en juego, log_entry_notes para las consecuencias que un criterio impone al propio registro, y under_specified cuando no se afirmó nada en absoluto. La capa de registro añade determination_final y clarification_required — ver Elicitación más abajo.

Lógica de determinación (determinista) — el árbol de decisión de 1904.4(b)(2) en orden:

  1. Si work_related es falso → no registrable (1904.5).

  2. Si new_case es falso → sin entrada nueva, pero actualiza la existente si los conteos de días o el resultado han cambiado (1904.6). El árbol enruta aquí; no se detiene simplemente.

  3. De lo contrario, si hay algún specific_case_criteria presente → registrable según 1904.8-1904.12, sin consultar en absoluto la lista de primeros auxilios.

  4. De lo contrario, si hay algún outcome presente → registrable (criterios generales de registro, 1904.7(b)(1)).

  5. De lo contrario, si hay algún significant_diagnosis presente → registrable incluso si solo se administraron primeros auxilios (1904.7(b)(7)).

  6. De lo contrario, si algún treatment no está en la lista cerrada de primeros auxilios → registrable (tratamiento médico más allá de primeros auxilios, 1904.7(b)(5)(i)).

  7. De lo contrario → no registrable (solo primeros auxilios y ningún criterio de caso específico).

El paso 3 existe porque 1904.4(a)(3) es una disyunción: 1904.7 o los casos específicos de 1904.8-1904.12. Sin él, un pinchazo con aguja contaminada tratado con limpieza y una venda devolvía "no registrable", con una citación adjunta, mientras que la herramienta de privacidad del mismo servidor lo llamaba correctamente caso de privacidad. Los criterios de registro que nunca consultan la lista de primeros auxilios deben verificarse antes que ella, no después.

Superficie del protocolo (las tres primitivas de MCP)

Este servidor usa el protocolo completo, no solo Tools:

  • Tools — las once determinaciones enumeradas en La cadena de triaje de incidentes más abajo. Cada una declara un outputSchema y devuelve structuredContent tipado, no una cadena JSON, y cada una está anotada con readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false — búsquedas puras, seguras y reintentables.

  • Resources — los quince conjuntos de datos se exponen directamente, de modo que un cliente puede cargar los datos de referencia como contexto en lugar de acceder a ellos solo mediante una llamada de herramienta. El modelo de datos es el producto; Resources es lo que lo hace visible. Las URIs son osha://data/<id>, donde <id> es la clave en src/datasets.ts — p. ej. osha://data/first-aid-treatments, osha://data/partially-exempt-industries, osha://data/privacy-cases.

  • Prompt — triage_incident recorre un incidente a través de toda la cadena como un único flujo de trabajo invocado por el usuario: alcance → empleador que registra → relación con el trabajo → caso nuevo → trabajo restringido → pérdida auditiva → registrabilidad → plazo de notificación → columna del Log 300 → caso de privacidad → establecimiento.

  • Elicitación — osha_assess_recordability resuelve el único caso límite que no debe adivinar: medicación de venta libre (OTC) frente a medicación de prescripción. La fuerza no prescrita es primeros auxilios; la fuerza de prescripción es tratamiento médico y registrable. Cuando la narrativa es silenciosa, el modelo pasa medication_unspecified_strength y la fuerza se resuelve preguntando a un humano, nunca eligiendo la herramienta.

    Resolución en dos niveles. La elicitación es una capacidad opcional de MCP, por lo que el servidor verifica getClientCapabilities() y elige su canal:

    El cliente anuncia elicitation

    Canal

    Resultado

    Sí

    El servidor pregunta al usuario directamente

    Resuelto en una llamada de herramienta

    No

    Devuelve determination_final: false + clarification_required

    El modelo pregunta en el chat y luego vuelve a llamar con el código resuelto

    De cualquier manera, la pregunta llega a un humano y la herramienta nunca adivina. El resultado provisional se mantiene conservador — recordable: true, base marcada como pendiente de confirmación — y clarification_required lleva la pregunta, la razón del CFR y el código de tratamiento exacto a enviar de vuelta para cada respuesta.

    En qué nivel cae un cliente determinado vale la pena verificarlo en lugar de asumirlo. Verificado aquí: el cliente de chat de Claude Desktop no anuncia capacidad de elicitation, y tampoco MCP Inspector 0.15.0 o 1.0.0. Los clientes agénticos pueden diferir, y un cliente que pregunta al usuario mediante su propio mecanismo se ve idéntico desde fuera. El servidor registra elicitation=supported|NOT supported en stderr al conectar — inícialo bajo cualquier cliente y lee esa línea.

Procedencia y caducidad forzada

RuleRecord<T> (ver src/types.ts) lleva reglas regulatorias: cfr_cite, source_url, last_verified y, donde eCFR las proporciona, amendment_history y editorial_note. No hay campo effective_date; los conjuntos de datos llevan el texto actual de eCFR, y last_verified indica la fecha de verificación regulatoria.

La caducidad se aplica mediante scripts/check-decay.ts, que hace fallar la compilación si el last_verified de cualquier registro supera su umbral de caducidad. Se ejecuta en cada push y en un horario semanal de CI, valida los destinos de source_url de las subpartes y verifica las entradas de editorial_note de eCFR.

La cadena de triaje de incidentes (incluida)

Once herramientas deterministas que siguen un incidente desde "alguien resultó herido" hasta una entrada de registro correcta:

  1. osha_check_recordkeeping_obligation (1904.1, 1904.2) — la pregunta que presupone cualquier otra determinación: ¿debe este empleador llevar registros en absoluto? La exención por tamaño se mide en toda la empresa con el empleo máximo del último año natural — no un promedio, no un solo centro. La exención por sector se aplica al establecimiento, y la herramienta la resuelve contra la lista cerrada de 82 códigos del Apéndice A cuando se le proporciona un código NAICS. Ambas son parciales: el informe de lesiones graves del 1904.39 sobrevive a cualquiera de las dos, que es la inferencia que un empleador exento se equivoca peligrosamente al hacer.

  2. osha_determine_recording_employer (1904.31) — una pregunta de umbral, no un paso: cuando la persona lesionada no está en nómina, ¿es siquiera un caso de este empleador? La supervisión día a día decide, no la nómina. Un temporal en nómina de una agencia cuyo trabajo usted dirige a diario es suyo para registrar; el mismo temporal bajo la supervisión de la agencia no lo es. Los autónomos quedan fuera de la Ley OSH por completo, y los propietarios o socios de una empresa individual no son empleados a efectos de registro. El (b)(4) exige que el caso se registre exactamente una vez — nunca en ambos registros.

  3. osha_assess_work_relatedness (1904.5) — la puerta sobre la que descansa todo lo demás, y hasta ahora el único juicio jurídico que este proyecto delegaba en el modelo. El 1904.5(a) presume la relación con el trabajo para cualquier cosa que surja en el entorno laboral; el 1904.5(b)(2) es una lista cerrada de nueve excepciones que pueden desvirtuarla. El veredicto es deliberadamente tri-valente — work_related, not_work_related o requires_judgment — porque el 1904.5 contiene vías que el propio reglamento asigna al empleador: origen poco claro (1904.5(b)(3)), situación de viaje (b)(6), trabajo en casa (b)(7) y la constatación de "únicamente" de la que depende toda excepción. Forzar esas vías a un booleano sería que la herramienta adivinara en la decisión más disputada de la Parte 1904. También zanja casos que la memoria recuerda al revés. Un accidente de vehículo de motor durante el trayecto en el aparcamiento de la empresa queda exceptuado en virtud del (b)(2)(vii); un resbalón y caída en el mismo aparcamiento no está cubierto por ninguna excepción y sigue siendo relacionado con el trabajo. Y la enfermedad mental invierte la dirección habitual — no relacionada con el trabajo a menos que el empleado aporte voluntariamente una opinión de un PLHCP (b)(2)(ix).

  4. osha_assess_new_case (1904.6) — ¿una entrada nueva en el Registro 300, o una actualización de una ya existente? La segunda condición de la conjunción del 1904.4(a). Separa los dos casos de recurrencia que el reglamento distingue deliberadamente: un episodio causado por una exposición en el lugar de trabajo es un caso nuevo (b)(2) — asma ocupacional desencadenada en la línea de producción — mientras que una enfermedad crónica cuyos síntomas reaparecen sin exposición se registra una sola vez (b)(1). Nótese que el (b)(1) no es una lista cerrada: el reglamento dice que los "ejemplos pueden incluir" cáncer, asbestosis, bisinosis y silicosis, así que la herramienta pregunta por el carácter de la afección en lugar de cotejar nombres de enfermedades. Es también la única herramienta del servidor que se remite a una autoridad externa. En virtud del (b)(3), un empleador no está obligado a consultar a un PLHCP, pero si lo ha consultado debe seguir la recomendación — así que una opinión de un PLHCP anula por completo la lógica de la regla, y las opiniones contradictorias devuelven requires_judgment porque sopesarlas es expresamente tarea del empleador.

  5. osha_evaluate_restricted_work (1904.7(b)(4)) — ¿cuenta realmente la restricción? No todas cuentan, y ambos errores mueven casos hacia el registro o fuera de él. Una restricción limitada al día de la lesión no cuenta (b)(4)(iii); una producción reducida mientras se siguen desempeñando todas las funciones habituales no cuenta (b)(4)(vi); "funciones habituales" significa actividades realizadas al menos una vez por semana (b)(4)(ii). Un turno parcial sí cuenta (b)(4)(v)), y los traslados comparten la columna de restricción (b)(4)(x)). La interesante es la (b)(4)(vii): cuando una recomendación vaga como "trabajo ligero" no puede aclararse con el PLHCP, el caso debe registrarse como trabajo restringido. Esa es la regulación resolviendo su propia duda a favor del registro — y la única regla de registro por defecto en la Parte 1904.

  6. osha_evaluate_hearing_loss (1904.10) — el único criterio de registro de la Parte 1904 que es aritmética pura, y la única herramienta aquí que calcula en lugar de consultar. Dos pruebas deben cumplirse ambas en el mismo oído: un cambio de umbral estándar de 10 dB respecto a la línea base, y un nivel auditivo total de 25 dB o más por encima del cero audiométrico, cada uno promediado a 2000, 3000 y 4000 Hz. Un STS en un oído y un nivel de 25 dB en el otro no se registra. El ajuste por edad se aplica solo a la prueba del cambio, nunca a la prueba de los 25 dB.

  7. osha_assess_recordability (1904.4) — ¿es registrable? (el ancla, arriba)

  8. osha_check_severe_injury_reporting (1904.39) — ¿debe notificarse a OSHA, y para cuándo? Devuelve la marca de tiempo límite real (8 horas para un fallecimiento, 24 para hospitalización / amputación / pérdida de un ojo) calculada desde el momento en que el empleador tuvo conocimiento del hecho, comprueba la ventana de elegibilidad desde el incidente y señala si el plazo ya está vencido.

  9. osha_classify_300_log_entry (1904.29) — qué columna de resultado del Registro 300 (G/H/I/J) según la regla del resultado más grave, la columna de tipo de lesión o enfermedad, y los recuentos de días limitados a 180.

  10. osha_check_privacy_case (1904.29(b)(6)-(9)) — ¿puede el nombre del empleado figurar en el registro en absoluto? Una segunda lista cerrada, y cerrada en ambas direcciones: el (b)(7) enumera los seis casos de privacidad, y el (b)(8) prohíbe tratar cualquier otra cosa como tal — así que un empleador no puede ampliarla por compasión ni ignorarla. Devuelve la entrada literal del registro ("privacy case") más las obligaciones que conlleva: la lista confidencial separada ((b)(6)), la discreción al describir el caso cuando la sola narrativa pudiera identificar al empleado ((b)(9)), y la supresión de datos cuando los registros se entregan a cualquier persona que no sea un representante gubernamental ((b)(10)).

  11. osha_route_to_establishment_log (1904.30) — qué Registro 300 de qué establecimiento, la última pregunta sobre un incidente individual. La regla va contra la intuición: un caso sigue al lugar, no a la persona. Alguien que se lesiona cubriendo un turno en otra planta del empleador se registra en el registro de esa planta, lo que mueve el número que impulsa su TRIR del centro. Una lesión lejos de todo establecimiento — en las instalaciones del cliente, en tránsito, en remoto — va al registro del centro donde el empleado trabaja normalmente.

Alcance: Parte 1904, y nada más

Todo esto responde a una pregunta — alguien se ha lesionado; ¿qué exige OSHA que registre y notifique? Eso es el 29 CFR Parte 1904 de principio a fin, y las once herramientas anteriores son las determinaciones que impone.

Distribución: un servidor y una Skill

Dos artefactos, porque responden a preguntas distintas. El servidor decide; la Skill sabe cuándo consultarlo.

El servidor — tres puntos de entrada, un mismo motor

Punto de entrada

Transporte

Para

dist/index.js

stdio

Claude Desktop, desarrollo local

dist/http.js

Streamable HTTP

un contenedor o un host de node

src/worker.ts

Streamable HTTP

Cloudflare Workers

Los tres llaman al mismo createServer() sobre las mismas once herramientas y quince conjuntos de datos — nada en src/tools/ sabe cuál está en ejecución. Esa portabilidad vino de dos decisiones anteriores más que de un esfuerzo de portado: las determinaciones son funciones puras, y datasets.ts es el único punto de contacto con el JSON.

Cada variante es sin estado — un servidor nuevo por petición, sin ids de sesión, sin nada retenido entre llamadas, porque cada herramienta es una consulta pura sobre datos incluidos. /health informa de la antigüedad de cada conjunto de datos frente a su umbral de caducidad y devuelve 503 cuando uno se queda obsoleto, de modo que un despliegue alojado se vigila con la misma regla que la compilación.

npm run start:http      # node host — PORT=3000 MCP_PATH=/mcp by default
npm run smoke:http      # boots it, drives it with a real client, checks /health

npm run dev:worker      # wrangler dev — runs under workerd, not Node
npm run smoke:worker    # boots workerd and drives it with a real client
npm run deploy:worker   # wrangler deploy

smoke:worker es la única comprobación que ejecuta las herramientas bajo workerd. Los otros dos smokes se ejecutan en Node y estructuralmente no pueden ver un built-in de node colándose en una ruta de código — que es exactamente lo que un despliegue sacaría a la luz primero. nodejs_compat está deliberadamente DESACTIVADO en wrangler.toml para que ese fallo sea ruidoso en desarrollo en lugar de silencioso.

El worker acepta solo POST. Un servidor sin estado no inicia mensajes, así que el flujo SSE de GET no lleva nada y permanecería abierto para siempre; workerd cancela una petición cuya respuesta nunca se completa. El 405 con Allow: POST es la forma que tiene el protocolo de decir que no existe flujo servidor-a-cliente.

Sin autenticación, a propósito. El servidor expone texto normativo publicado, no almacena nada y no tiene efectos secundarios, así que el control de acceso pertenece delante de él — Cloudflare Access o una capa OAuth — en lugar de a medio implementar dentro.

Limitación de velocidad

La limitación de velocidad es la excepción, y vive en el worker en lugar de delante de él. El despliegue está en workers.dev, que no es una zona de la cuenta, así que una regla de limitación de velocidad del WAF no tiene dónde anclarse. Declarada como un binding [[ratelimits]] en wrangler.toml, lo que también significa que se revisa, versiona y viaja con el despliegue en lugar de vivir en un panel que nadie compara.

300 peticiones por minuto por IP de cliente. Deliberadamente generoso: el limitador se basa en la IP, y un equipo de seguridad detrás de un único NAT corporativo comparte una sola clave. Una cadena de triaje son unas 15 peticiones, así que varias personas trabajando a la vez superan legítimamente las 150/minuto. Esto está dimensionado para cortar a un modelo en bucle sobre un error — el fallo que de verdad amenaza un despliegue alojado — no para medir el uso normal. Superar el límite devuelve 429 con Retry-After.

/health está por encima de la comprobación, así que un monitor de disponibilidad que sondea con una programación fija nunca puede ser lo que agote el presupuesto. La aplicación se hace por centro de datos en lugar de coordinarse globalmente, así que es un corte más que una cuota exacta.

Lo que reciben las herramientas

El servidor no recupera nada y no almacena nada. Pero los argumentos sí fluyen hacia dentro, y describen un incidente real, así que "sin datos de usuario" es una afirmación sobre el almacenamiento que no dice nada sobre el tránsito. La distinción merece enunciarse con claridad, porque es la que un equipo de EHS tiene que evaluar.

Ninguna entrada es un identificador. No hay ningún campo en ningún esquema para un nombre, número de empleado, fecha de nacimiento, dirección o narrativa de texto libre — cada entrada es un atributo del caso (work_related, days_away_from_work, treatments) y la determinación no necesita nada más. Eso es una propiedad de los esquemas, no una política: no hay campo donde poner un nombre. La Skill también instruye al modelo para no trasladar identidad a una llamada, así que la restricción se mantiene en ambos extremos — véase Pase hechos, nunca identidades.

Algunos atributos son sensibles de todos modos. osha_check_privacy_case toma exactamente las categorías que enumera el 1904.29(b)(7) — sexual_assault, mental_illness, hiv_hepatitis_or_tuberculosis, contaminated_needlestick_or_sharps. El reglamento las señala precisamente porque son las que no deben aparecer en un registro que un compañero pueda leer. Solo-atributos tampoco es lo mismo que anónimo: un código de naturaleza más una fecha de incidente en un establecimiento de nueve personas puede identificar a alguien ante cualquiera que trabaje allí.

Dónde aterriza eso depende del transporte, y solo del transporte:

Punto de entrada

Dónde van los argumentos

stdio

permanecen en la máquina que ejecuta el servidor; el host de IA todavía los ve

node HTTP / worker

cruzan la red hasta quienquiera que opere ese despliegue

No se registra nada en ningún sentido — ni registro de solicitudes, ni registro de llamadas a herramientas, ni exitosas ni fallidas. Esto es deliberado. Un registro de estos argumentos sería un repositorio regulado en sí mismo, en un servidor que por lo demás no tiene nada que regular, y las determinaciones ya son reproducibles a partir de las entradas más la versión del conjunto de datos last_verified que se incluye en cada respuesta. La procedencia en la respuesta cumple la función que tendría un registro de auditoría, sin la retención.

Por lo tanto: si está tratando casos reales bajo GDPR o HIPAA, ejecute stdio, o auto-aloje el worker en una infraestructura que usted controle. Apuntar datos de incidentes regulados a una copia alojada por terceros de este servidor significa enviar atributos de lesiones a un tercero con el que no tiene ningún acuerdo. Las determinaciones son funciones puras sobre JSON incluido — auto-alojar cuesta un wrangler deploy y no cambia nada de las respuestas.

Validación de Host y Origin

La autenticación trata de quién puede preguntar. La validación de host trata de que un navegador sea inducido a preguntar en nombre de otro, lo que ningún gateway ascendente puede corregir a posteriori — así que esa parte se maneja en src/httpGuard.ts y se aplica a ambos puntos de entrada HTTP.

El ataque que cierra es el DNS rebinding: un dominio atacante se re-resuelve a 127.0.0.1, el navegador trata la solicitud como de mismo origen y la envía sin preflight, y un servidor MCP ejecutado localmente responde. La cabecera Host es lo que aún lo delata — lleva el dominio del atacante — así que una lista de permitidos de host con coincidencia exacta es la comprobación que funciona.

Variable

Node (dist/http.js)

Worker

HOST

dirección de enlace, por defecto 0.0.0.0

—

MCP_ALLOWED_HOSTS

por defecto localhost:$PORT, 127.0.0.1:$PORT, [::1]:$PORT

sin definir = sin restricciones

MCP_ALLOWED_ORIGINS

sin definir = sin restricciones

sin definir = sin restricciones

Ambos aceptan una lista separada por comas; * desactiva la comprobación cuando un gateway delante es el que decide. Origin solo se comprueba cuando la cabecera está presente, porque los clientes MCP que no son de navegador no envían una. /health queda fuera de la lista de permitidos — un monitor de disponibilidad no es el modelo de amenaza.

El punto de entrada de node usa por defecto solo loopback. Una implementación en contenedor o con proxy inverso se alcanza por otro nombre y debe establecer MCP_ALLOWED_HOSTS; falla con un 403 que nombra la cabecera que vio, lo que es un arreglo de cinco segundos. El defecto opuesto es un agujero que nadie nota. Ten en cuenta que la dirección de bind no es la protección — el bind a 0.0.0.0 sigue siendo el defecto para que los contenedores funcionen, y la lista de permitidos es lo que hace que eso sea seguro.

Las solicitudes rechazadas reciben 403 con un error JSON-RPC -32000. Los cuerpos sobredimensionados (>1 MB) reciben 413, el JSON malformado recibe 400 — los errores del cliente no se registran como incidentes.

La Skill

skills/osha-incident-triage/ lleva el procedimiento: cuándo se aplica la cadena, qué hay que establecer antes de llamar, cómo presentar una determinación y qué no pueden decidir las herramientas. Contiene orientación de proceso para el triaje de incidentes y no lleva lógica regulatoria directamente.

Estructura

La lógica de determinación es pura y comprobable; el servidor es el cableado que la rodea.

src/
  index.ts              stdio entry point — Claude Desktop, local development
  http.ts               Streamable HTTP entry point — container / node host
  worker.ts             Cloudflare Workers entry point — same server, fetch handler
  server.ts             createServer() factory + registerRuleTool/toolResult helpers
  httpGuard.ts          Host/Origin allowlisting shared by both HTTP entry points —
                        one implementation, since Node and workerd share no middleware
  datasets.ts           the one place JSON assets are loaded and named — static imports,
                        so the same module resolves with or without a filesystem
  types.ts              RuleRecord, Provenance, and the ruleRecord() constructor
  md.d.ts               ambient declaration letting SKILL.md be imported as a string,
                        so the worker can serve it without a filesystem
  tools/                one pure function per determination — no MCP imports except
                        medicationStrength.ts, which owns the elicitation exchange
  registrations/
    tools/              one registerX.ts per tool + a barrel; metadata and summaries
    resources.ts        generated from the DATASETS table
    prompts.ts          triage_incident

Añadir una herramienta significa un archivo en src/tools/ (la regla), uno en src/registrations/tools/ (cómo se describe y resume) y una línea en el barril. El prefijo register mantiene esos nombres de archivo distintos de sus contrapartes en src/tools/ en la barra de pestañas del editor.

Dos invariantes que vale la pena mantener: la procedencia se ensambla solo con ruleRecord(), y los Recursos se generan desde la misma tabla DATASETS de la que cargan las herramientas, así que un conjunto de datos no puede publicarse bajo una ruta que ninguna herramienta lea.

Integración continua

.github/workflows/ci.yml ejecuta typecheck, build, pruebas unitarias y suites de humo en Node 20 y 22.

La comprobación de decaimiento y npm audit se ejecutan ambos con los mismos disparadores que el resto de CI — push, pull request y un horario semanal — mantenidos como trabajos separados para que cada fallo sea legible por sí mismo en lugar de una X roja entre varias. npm audit bloquea el build en avisos de vulnerabilidad de producción de bajo nivel; los avisos de dependencias de desarrollo se informan, no bloquean. El horario semanal es lo que detecta un aviso publicado contra una versión de dependencia ya en main, donde nada más empujaría para disparar una re-comprobación.

tsconfig.json excluye test/, así que tsc --noEmit comprueba solo src/ y ts-jest comprueba los archivos de test durante npm test.

Control de cambios y versionado

CHANGELOG.md rastrea todos los cambios en dos dimensiones de publicación independientes:

  • Código: La lógica de determinación, los esquemas de herramientas y los transportes del servidor siguen Semantic Versioning.

  • Datos regulatorios: los conjuntos de datos JSON de eCFR incluidos en src/data/. Re-verificar un conjunto de datos contra el texto actual de eCFR mueve su fecha last_verified y se publica como actualización de parche, incluso cuando el texto regulatorio no ha cambiado, manteniendo procedencia auditable para los equipos de cumplimiento.

  • Decaimiento forzado: CI ejecuta scripts/check-decay.ts semanalmente para fallar el build si algún conjunto de datos supera su umbral de decaimiento de 365 días sin re-verificación manual.

  • Publicaciones: las etiquetas de versión (vX.Y.Z) en GitHub disparan .github/workflows/release.yml para ejecutar los conjuntos de validación completos (typecheck, tests, smokes, decay, audit) y crear una Release de GitHub verificada.

Desarrollar

npm install
npm run build       # tsc + copy src/data → dist/data
npm test            # jest — deterministic logic
npm run check-decay # build-breaking staleness trap
npm run smoke       # end-to-end: spawn the server, list tools/resources/prompts, call a tool

Conéctate localmente con npx @modelcontextprotocol/inspector, o añádelo a claude_desktop_config.json apuntando a dist/index.js.

npm run smoke:worker y npm run dev:worker necesitan Node 22 o más nuevo, porque wrangler lo necesita. Todo lo demás funciona en Node 20, y engines se queda en >=20 deliberadamente: ese campo es una afirmación sobre quién puede instalar y ejecutar el servidor, que solo necesita el SDK y zod. Wrangler es herramienta de desarrollo y nunca llega a un consumidor, así que su requisito no es el del paquete. CI mantiene Node 20 en la matriz exactamente por esa razón y omite solo el smoke de worker allí.

Evaluaciones

evals/recordkeeping-evals.xml — cuarenta y siete preguntas que comprueban si un LLM llega a la respuesta correcta a través de las herramientas, lo que los tests unitarios no pueden cubrir. Cada respuesta se produjo conduciendo el servidor construido con un cliente MCP real; el rastro está en evals/README.md. La mayoría de las cuarenta y siete tienen una respuesta incorrecta intuitiva que un modelo que razona desde la memoria alcanzará.

Descargo de responsabilidad

Solo referencia y triaje. No es asesoramiento legal, no es una determinación médica. Los casos límite de registrabilidad requieren frecuentemente un PLHCP o asesoría. La relación con el trabajo (1904.5) se determina solo a lo largo de sus rutas deterministas; el origen poco claro, el estado de viaje, el trabajo en casa y cualquier hallazgo de "únicamente" no establecido devuelven requires_judgment en lugar de un veredicto.

Available Tools

11 tools
osha_assess_new_caseAssess New Case vs. Continuation (29 CFR 1904.6)A
Read-onlyIdempotent

Determine whether an injury or illness is a NEW case or a continuation of one already on the 300 Log — the second condition of the 1904.4(a) conjunction. Run this after osha_assess_work_relatedness and before osha_assess_recordability, and pass its new_case result through. Key distinctions it settles: a recurrence CAUSED by a workplace exposure is a new case (1904.6(b)(2), e.g. an occupational asthma episode), while a chronic illness whose symptoms recur WITHOUT exposure is recorded only once (1904.6(b)(1)). A PLHCP recommendation, once sought, is binding and overrides the rule logic (1904.6(b)(3)). Returns work_case verdicts of new_case, not_new_case, or requires_judgment — the last when PLHCP opinions conflict or causation is unestablished. Treat requires_judgment as a question for the user, never as a licence to pick. Reference and triage only — not legal advice or a medical determination.

NameRequiredDescriptionDefault
plhcp_opinionNoAny physician or licensed health care professional recommendation on whether this is a new case or a recurrence. Under 1904.6(b)(3) an employer need not seek one, but MUST follow it once sought — so this OVERRIDES the rule logic. Use 'conflicting' when two or more PLHCPs disagree; the employer must then decide which is most authoritative.none
causation_is_clearNoIs it clear whether a workplace event caused the current signs or symptoms, as opposed to the condition simply continuing? Pass false when the narrative does not establish this; the tool will return requires_judgment rather than pick.
recovered_completely_from_priorNoHad the employee recovered completely from the prior recorded case — ALL signs and symptoms had disappeared — before the current signs or symptoms appeared? (1904.6(a)(2))
prior_recorded_same_type_same_body_partYesHas the employee previously experienced a RECORDED injury or illness of the same type affecting the same part of the body? (1904.6(a)(1)) If false, the case is new and nothing else needs deciding.
workplace_event_caused_current_symptomsNoDid an event or exposure in the workplace cause the current signs or symptoms? (1904.6(b)(2)) An episode of occupational asthma triggered by a workplace exposure is a new case even though the asthma itself is not new.
chronic_recurs_without_workplace_exposureNoIs this an occupational illness whose signs or symptoms may recur or continue in the ABSENCE of a workplace exposure? Examples may include occupational cancer, asbestosis, byssinosis and silicosis (1904.6(b)(1)). This is a description of character, NOT a closed list of illnesses — judge the condition, do not match the name. Such cases are recorded once only.

Output Schema

NameRequiredDescription
kindYes
valueYes
cfr_citeYes
source_urlYes
last_verifiedYes

TDQS

A4.5/5.0
Behavior3/5

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

The annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the basic safety and side-effect profile. The description adds meaningful context beyond that by explaining the binding PLHCP override (1904.6(b)(3)) and clarifying that requires_judgment is a non-decision state to be escalated, not acted upon. It does not detail return-format specifics, but with an output schema present and the annotations already carrying the safety burden, a 3 is appropriate.

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

Conciseness4/5

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

The description is compact and well-structured: purpose first, then workflow ordering, then the key legal distinctions, then the output verdicts and a caution about misuse. Each sentence carries distinct regulatory or procedural information. It loses one point for density — the 1904.6(b)(3) PLHCP rule is described in a long single sentence, and the overlap between the description's example ('occupational asthma episode') and the schema's parameter description is some slight redundancy, but no sentence is wasted.

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

Completeness5/5

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

Given 100% parameter coverage, an output schema, and read-only/idempotent annotations, the description fills every remaining gap: imputed workflow position among 10 sibling tools, special-case handling (PLHCP binding), and the output's semantics (requires_judgment means ask the user). No side-effect or resource-lifetime concerns exist for this read-only classifier, so nothing is arguably missing to invoke/triage correctly.

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

Parameters5/5

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

Schema coverage is 100% (all 6 parameters have rich schema descriptions), so the baseline is already 3. The description adds substantial value beyond the schema by interpreting the regulatory context: why PLHCP opinion overrides the logic, what 'conflicting' means in practice, and what makes requires_judgment occur. The parameter 'causation_is_clear' gets practical meaning — 'Pass false when the narrative does not establish this' — which the schema itself does not fully convey.

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

Purpose5/5

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

The description opens with a specific verb and resource: 'Determine whether an injury or illness is a NEW case or a continuation of one already on the 300 Log.' It precisely names the second condition of the 1904.4(a) conjunction and distinguishes itself from sibling tools by placing itself explicitly between osha_assess_work_relatedness and osha_assess_recordability. This gives an agent an unambiguous understanding of what the tool does and how it differs from the rest of the osha_* family.

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

Usage Guidelines5/5

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

The description gives explicit sequencing: 'Run this after osha_assess_work_relatedness and before osha_assess_recordability, and pass its new_case result through.' It also lists key distinctions the tool settles and provides a clear behavioral rule for ambiguous results: 'Treat requires_judgment as a question for the user, never as a licence to pick.' This is strong when-to-use guidance with a direct exclusion of misuse.

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

osha_assess_recordabilityAssess OSHA Recordability (29 CFR 1904.4)A
Read-onlyIdempotent

Determine whether a work-related injury or illness is OSHA recordable under the 1904.4 decision tree: work-related AND a new case AND meeting either the general recording criteria of 1904.7 OR a specific-case criterion of 1904.8-1904.12 (needlestick, medical removal, hearing loss, tuberculosis). Map the incident narrative to the controlled inputs. The tool applies the closed first-aid list in 1904.7(b)(5)(ii) deterministically and returns a cited determination. Reference and triage only — not legal advice or a medical determination. If the result has determination_final=false, it is provisional: follow the clarification_required instruction, ask the user, and call this tool again with their answer.

NameRequiredDescriptionDefault
new_caseYesIs this a new case, not a continuation of a previously recorded one? (1904.6)
outcomesYesGeneral recording criteria outcomes present in this case. REQUIRED — pass [] only when the narrative affirmatively establishes there were none. If the narrative is silent on time off or work restrictions, ask the user before calling; do not pass [] to mean 'unknown'.
treatmentsYesControlled treatment codes. Map the incident narrative to these codes. First-aid codes come from the closed 1904.7(b)(5)(ii) list; anything else is medical treatment. Use 'other_medical_treatment' if unsure. If the report mentions medication but not its strength, use 'medication_unspecified_strength' — the strength will be resolved by asking the user, either by the server or by you. Never guess it. REQUIRED — pass [] only when the narrative affirmatively establishes no treatment was given. Note two codes are NEITHER first aid nor medical treatment: 'observation_or_counseling_only' and 'diagnostic_procedure_only' (1904.7(b)(5)(i)) — an x-ray or a clinic visit to be checked out does not make a case recordable. And the professional status of whoever provided the treatment is irrelevant (1904.7(b)(5)(iv)): a bandage is first aid even when a physician applies it.
work_relatedYesDid the work environment cause or contribute to the injury/illness? (1904.5)
significant_diagnosesYesSignificant injuries/illnesses that are recordable even if only first aid was given (1904.7(b)(7)). REQUIRED — pass [] only when affirmatively established, not when the narrative is silent.
specific_case_criteriaYesSpecific-case recording criteria under 1904.8-1904.12, which are INDEPENDENT of the first-aid list: a case meeting one of these is recordable even when only first aid was given. One of: contaminated_needlestick_or_sharps, medical_removal, occupational_hearing_loss_sts, tuberculosis_infection, bloodborne_exposure_with_diagnosis. REQUIRED — pass [] only when affirmatively established. Note 'occupational_hearing_loss_sts' asks whether the 1904.10 audiometric test is already MET; the tool does not compute the shift.
plhcp_recommendations_not_followedNoSituations where a PLHCP recommended something and the employee did not follow it. The case is recordable anyway — what was recommended controls, not what the employee did. One of: days_away_recommended_but_employee_worked, restriction_recommended_but_employee_worked_normally, medical_treatment_recommended_but_declined. (1904.7(b)(3)(ii), (b)(4)(viii), (b)(5)(v))
tuberculosis_test_was_pre_employmentNoFor a tuberculosis case only: was the positive skin test obtained at a PRE-EMPLOYMENT physical? If so the case is NOT recordable (1904.11(b)(1)) — the employee was not occupationally exposed to a known active case in your workplace.
medical_removal_was_voluntary_and_earlyNoFor a medical removal only: was the employee removed VOLUNTARILY, before the medical removal levels required by the OSHA standard were reached? If so the case is NOT recordable (1904.9(b)(3)) — an employer who acts early is not penalised. Leave false when the removal met the standard's criteria.

Output Schema

NameRequiredDescription
kindYes
valueYes
cfr_citeYes
source_urlYes
last_verifiedYes

TDQS

A4.5/5.0
Behavior5/5

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

Beyond the already helpful annotations of readOnlyHint, idempotentHint, and destructiveHint, the description adds meaningful behavioral detail: the tool applies the closed first-aid list deterministically, returns a cited determination, marks results provisional when needed, and requires a follow-up interaction when clarification is pending. It also discloses the limitation that this is not legal advice or a medical determination.

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

Conciseness5/5

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

The description is thorough and front-loaded with the main decision. Every sentence contributes something valuable: the decision rule, the deterministic behavior, the input-mapping requirement, the disclaimer, and the follow-up workflow. It is long because it needs to be, but it still feels tight and structured.

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

Completeness5/5

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

For a regulatory decision tool with nine parameters, rich annotated safety metadata, and a complex sibling set, the description is complete. It covers the decision tree, the output provisional state, user clarification flow, mapping of narrative input to controlled fields, and the non-legal/non-medical disclaimer. An agent has enough information to invoke the tool and respond to the results correctly.

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

Parameters3/5

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

Schema description coverage is 100%, and each parameter already carries detailed regulatory guidance, so the description does not need to re-explain individual inputs. It adds a high-level instruction to map the incident narrative to controlled inputs, but most of the substantive usage semantics are already embedded in the schema.

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

Purpose5/5

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

The description names a specific action and resource: 'Determine whether a work-related injury or illness is OSHA recordable under the 1904.4 decision tree.' It then spells out the exact conditions of the decision tree, and the resource and scope are clearly distinct from sibling tools that assess only one component such as work-relatedness or new-case status.

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

Usage Guidelines4/5

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

The description provides clear operational context by stating 'Reference and triage only' and by specifying what to do when the result is provisional: follow the clarification_required instruction, ask the user, and call again. However, it does not explicitly name sibling tools or give exclusion conditions for when a caller should use one of them instead.

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

osha_assess_work_relatednessAssess Work-Relatedness (29 CFR 1904.5)A
Read-onlyIdempotent

Determine whether an injury or illness is work-related — the gate every other Part 1904 determination depends on. 1904.5(a) presumes work-relatedness for anything arising from the work environment unless one of the nine closed exceptions in 1904.5(b)(2) applies. Run this BEFORE osha_assess_recordability and pass its work_related result through. Returns one of three verdicts: work_related, not_work_related, or requires_judgment — the last when the regulation itself calls for the employer's evaluation (unclear origin under 1904.5(b)(3), travel status, working at home) or when an exception's 'solely' requirement is not established. Treat requires_judgment as a question to put to the user, never as a licence to pick. Reference and triage only — not legal advice.

NameRequiredDescriptionDefault
origin_is_clearYesIs it clear whether the precipitating event occurred at work or away from work? Pass false when the narrative genuinely does not establish this — 1904.5(b)(3) then requires the employer to evaluate the employee's duties and environment, which this tool cannot do.
claimed_exceptionYesWhich 1904.5(b)(2) exception is claimed, if any. Use 'none' when no exception is asserted. One of: member_of_general_public, symptoms_surface_at_work_only, voluntary_wellness_or_recreation, personal_food_or_drink, personal_tasks_outside_working_hours, personal_grooming_self_medication_or_self_inflicted, commuting_motor_vehicle_on_company_lot, common_cold_or_flu, mental_illness_without_plhcp_opinion, none.
special_situationNoWhether the employee was on travel status (1904.5(b)(6)) or working at home (1904.5(b)(7)). Both are fact-heavy and resolve to requires_judgment with the governing test returned.none
aggravation_tests_metNoWhich 1904.5(b)(4) significant-aggravation tests the workplace event caused. Closed list — nothing else counts as significant aggravation. One of: death_but_for_work_event, loss_of_consciousness_but_for_work_event, days_away_restriction_or_transfer_but_for_work_event, medical_treatment_needed_or_changed.
pre_existing_conditionNoIs this a pre-existing condition — one that resulted solely from a non-work-related event outside the work environment (1904.5(b)(5))? If so it is work-related only if significantly aggravated.
exception_solely_establishedNoHas it been affirmatively established that the injury results SOLELY from the claimed exception? Every 1904.5(b)(2) exception requires this and it is a factual finding, not a lookup. Pass false when unverified — the tool will return requires_judgment rather than apply the exception.
occurred_in_work_environmentYesDid the event or exposure occur in the work environment as defined by 1904.5(b)(1) — the establishment and other locations where employees work or are present as a condition of employment, including equipment and materials used in the course of work?
mental_illness_plhcp_opinion_volunteeredNoFor a mental illness only: has the employee VOLUNTARILY given the employer a PLHCP opinion stating the illness is work-related? Under 1904.5(b)(2)(ix) a mental illness is not work-related without one.

Output Schema

NameRequiredDescription
kindYes
valueYes
cfr_citeYes
source_urlYes
last_verifiedYes

TDQS

A4.7/5.0
Behavior5/5

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

Annotations already indicate read-only, idempotent, and non-destructive behavior. The description adds valuable behavioral context beyond that: it explains that the tool returns one of three verdicts, specifies the exact conditions that trigger requires_judgment, and includes a not-legal-advice caveat. No contradiction with annotations.

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

Conciseness5/5

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

The description is detailed but efficiently front-loaded with the core purpose, then the workflow ordering, verdict semantics, and handling guidance. Each sentence contributes distinct information: regulatory basis, tool sequencing, return values, requires_judgment behavior, and scope disclaimer.

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

Completeness5/5

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

For a tool with 8 parameters and an output schema, the description provides enough operational context for an agent to call it correctly: when to run it, what it returns, why requires_judgment appears, and how to respond to it. The output schema covers return structure, so the description does not need to restate that.

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

Parameters3/5

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

Schema description coverage is 100%, so the input schema fully documents all parameters and enums. The tool description itself does not add parameter-level detail, but it does add useful higher-level context about how the result should be used. Per the baseline for complete schema coverage, a 3 is appropriate.

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

Purpose5/5

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

The description opens with a specific verb and resource: 'Determine whether an injury or illness is work-related.' It clearly identifies the tool's role as the gate for Part 1904 determinations and distinguishes it from the sibling tool osha_assess_recordability by instructing the agent to run this tool first.

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

Usage Guidelines5/5

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

The description gives explicit workflow guidance: 'Run this BEFORE osha_assess_recordability and pass its work_related result through.' It also tells the agent how to handle the requires_judgment verdict — 'put to the user, never as a licence to pick' — and frames the tool as 'Reference and triage only.'

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

osha_check_privacy_caseCheck Privacy Concern Case (29 CFR 1904.29(b)(6)-(9))A
Read-onlyIdempotent

Determine whether a recordable case is a privacy concern case, meaning the employee's name must NOT be entered on the OSHA 300 Log. 1904.29(b)(7) is a closed list — injury to an intimate body part or the reproductive system, sexual assault, mental illness, HIV/hepatitis/tuberculosis, a contaminated needlestick or sharps cut, and other illnesses where the employee voluntarily asks to be left off. 1904.29(b)(8) forbids treating anything else as a privacy case. Returns the required log entry and the confidential-list and redaction obligations that follow, plus the only three recipients who may receive the forms with identifying information intact (1904.29(b)(10)). Run this after a case is determined recordable.

NameRequiredDescriptionDefault
natureYesThe nature of the case, mapped from the incident narrative. Use 'none_of_these' if the case does not match any enumerated category. One of: intimate_body_part_or_reproductive_system, sexual_assault, mental_illness, hiv_hepatitis_or_tuberculosis, contaminated_needlestick_or_sharps, other_illness_employee_requested, none_of_these.
is_illnessNoIs this an illness (not an injury)? Only relevant to 1904.29(b)(7)(vi), which covers other ILLNESSES and never injuries.
employee_requested_name_omittedNoDid the employee voluntarily request that their name not be entered on the log? Only relevant to 1904.29(b)(7)(vi), which covers other ILLNESSES.

Output Schema

NameRequiredDescription
kindYes
valueYes
cfr_citeYes
source_urlYes
last_verifiedYes

TDQS

A4.3/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the agent knows it's a safe, read-only operation. The description adds valuable behavioral context beyond annotations: it specifies what the tool returns (required log entry, confidential-list and redaction obligations, and the only three recipients) and warns about the closed-list prohibition (1904.29(b)(8)), which prevents misapplication. This enriches the agent's understanding of side effects and output.

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

Conciseness4/5

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

The description is moderately long but each sentence carries substantive information. The core purpose is front-loaded in the first sentence, followed by the closed-list explanation, output summary, and usage timing. For a complex regulatory topic requiring precision, this structure is efficient and not padded. It is slightly denser than necessary but appropriate given the need to convey legal nuances.

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

Completeness4/5

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

The description covers the essential elements: what the tool determines, what it returns, when to invoke it, and the closed-list constraint. Since an output schema exists (has output schema: true), the return structure is presumably detailed there, but the description mentions the key outputs (log entry, confidential-list, redaction obligations, three recipients) to orient the agent. It does not explicitly address edge cases like 'none_of_these' returning false, but the schema and closed-list description imply that. Overall, it is complete enough for a read-only classification tool.

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

Parameters4/5

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

Schema description coverage is 100%, so the parameters are fully documented in the input schema. The tool description adds meaning by explaining the regulatory basis for the enum values (e.g., '1904.29(b)(7) is a closed list — injury to an intimate body part or the reproductive system, sexual assault...') and clarifies that 'other_illness_employee_requested' is the only category that requires both is_illness and employee_requested_name_omitted. This helps the agent map incident narratives to the correct enum value and understand the conditional logic.

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

Purpose5/5

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

The description states a specific verb ('Determine'), a precise resource ('whether a recordable case is a privacy concern case'), and the core consequence (name must NOT be entered on the OSHA 300 Log). It explicitly distinguishes from siblings by indicating this runs after recordability is established, which is not obvious from any other tool. The mention of the closed list and prohibition adds specificity.

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

Usage Guidelines4/5

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

It clearly indicates when to run the tool ('Run this after a case is determined recordable') and provides context for the input nature by enumerating the closed list. It does not explicitly name alternative tools for different steps, but the instruction 'after a case is determined recordable' implicitly separates it from recordability assessment tools like osha_assess_recordability. The guidance is sufficient for correct usage.

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

osha_check_recordkeeping_obligationCheck Whether Recordkeeping Applies (29 CFR 1904.1)A
Read-onlyIdempotent

The threshold question every other Part 1904 determination assumes: is this employer required to keep OSHA injury and illness records at all? Run this FIRST for any small employer or any establishment that may be in a partially exempt industry — otherwise the chain will confidently instruct them to make 300-Log entries for a log they need not keep. Two things are commonly got backwards: the size exemption is measured across the ENTIRE COMPANY, not one establishment (1904.1(b)(1)), and it uses PEAK employment during the last calendar year, not an average or year-end figure (1904.1(b)(2)). A written request from OSHA or BLS under 1904.41/1904.42 defeats the exemption. CRITICALLY, the exemption is PARTIAL: 1904.39 severe-injury reporting binds every employer covered by the OSH Act regardless — an exempt employer still owes OSHA the 8-hour fatality call. Supply establishment_naics_code and the tool resolves the 1904.2 industry question itself against the closed Appendix A list, matching on the first four digits. Reference and triage only.

NameRequiredDescriptionDefault
establishment_naics_codeNoThe establishment's NAICS code, 4 to 6 digits. Supply this and the tool looks it up against the closed Appendix A list itself — the match is on the first FOUR digits, since Appendix A lists industry groups. If you do not know the code, omit it and use establishment_in_partially_exempt_industry instead.
notified_in_writing_to_keep_recordsNoHas OSHA or the Bureau of Labor Statistics informed the employer IN WRITING that it must keep records under 1904.41 or 1904.42? Appendix A extends this to a STATE AGENCY operating under the authority of OSHA or the BLS. Such a request defeats BOTH exemptions — 1904.1(a)(1) for size, 1904.2(a)(1) for industry.
company_peak_employees_last_calendar_yearYesThe PEAK number of employees across the ENTIRE COMPANY at any time during the last calendar year (1904.1(b)(1)-(b)(2)). Not an average, not a year-end headcount, and not a single establishment's count — if the company touched 11 employees for one week, it is over the threshold.
establishment_in_partially_exempt_industryNoFallback for when the NAICS code is unknown: is this ESTABLISHMENT classified in a partially exempt industry under 1904.2? Ignored when establishment_naics_code is supplied, because the tool then determines it. Note this exemption attaches to the establishment, whereas the size exemption applies to the whole company.

Output Schema

NameRequiredDescription
kindYes
valueYes
cfr_citeYes
source_urlYes
last_verifiedYes

TDQS

A4.7/5.0
Behavior4/5

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

Annotations declare readOnlyHint=true, openWorldHint=false, idempotentHint=true, destructiveHint=false. The description adds meaningful behavioral context beyond those: it explains the size exemption measurement (entire company, peak employment), the industry exemption resolution against Appendix A, the partial nature of the exemption (1904.39 still binds), and that written notice defeats the exemption. It also notes the tool resolves the 1904.2 industry question itself. No contradictions. The only minor gap is not detailing what the return value looks like, but output schema exists and the description says 'Reference and triage only', which hints at the read-only consultative nature.

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

Conciseness4/5

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

The description is front-loaded with the critical 'Run this FIRST' instruction, then covers key behavioral traps. It is structured in logical flow: purpose, when to use, common mistakes, exceptions, and parameter hints. It is somewhat dense — the sentences are long and packed with regulatory citations. But every sentence earns its place: each clause adds a distinct fact (coverage scope, peak employment, written request exception, partial exemption). Slight deduction for density that may slow parsing, but not for waste.

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

Completeness5/5

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

For a complex regulatory tool with 4 parameters (including a fallback boolean), the description and parameter-level detail together cover the key nuanced behaviors: the across-company scope, peak employment, industry exemption resolution, the written-notice defeat, and the partial exemption caveat. With output schema present, return format is not a gap. The sibling set includes many downstream chain tools, and this description establishes itself as the entry point. The completeness is high for the tool's complexity.

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

Parameters5/5

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

Schema description coverage is 100%. The description adds significant meaning beyond each property description. For company_peak_employees_last_calendar_year it emphasizes 'PEAK', 'ENTIRE COMPANY', 'not an average, not a year-end headcount', with an illustrative example ('if the company touched 11 employees for one week, it is over the threshold'). For establishment_naics_code it explains the 4-digit matching logic against Appendix A and the fallback to boolean. For notified_in_writing it adds context about state agencies and that it defeats both exemptions. This goes well beyond the schema's basic descriptions.

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

Purpose5/5

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

The description states a specific verb and resource: 'check whether recordkeeping applies' under 29 CFR 1904.1, and frames it as the threshold question before all other Part 1904 determinations. It clearly distinguishes from siblings by naming the first step in a chain and explicitly instructing to 'Run this FIRST'. The title reinforces the regulatory citation, and the description exceeds mere tautology by explaining the consequence of skipping this check.

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

Usage Guidelines5/5

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

Explicitly tells the agent when to use: 'Run this FIRST for any small employer or any establishment that may be in a partially exempt industry'. It gives a clear when-not condition: 'otherwise the chain will confidently instruct them to make 300-Log entries for a log they need not keep.' It also reveals two common mistakes to guard against, which adds practical usage context. No direct alternative named, but the sibling set context implies the chain, and the description frames this as the gate.

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

osha_check_severe_injury_reportingCheck Severe-Injury Reporting Deadline (29 CFR 1904.39)A
Read-onlyIdempotent

Determine whether a fatality, in-patient hospitalization, amputation, or loss of an eye must be reported to OSHA, and compute the actual reporting deadline (8 hours for a fatality, 24 hours for the others) from when the employer learned of it. Also checks the eligibility window from the incident. Datetimes must be full ISO 8601. Applies the 1904.39(b)(11) amputation definition (a severed ear, avulsion, degloving or chipped tooth is NOT an amputation), the (b)(10) rule that a hospitalization for observation or diagnostics alone is not reportable, and the (b)(3)-(b)(4) exclusions for public-road motor vehicle accidents outside construction work zones and events on commercial or public transport. Every one of those still leaves the case RECORDABLE. Reference and triage only — not legal advice.

NameRequiredDescriptionDefault
outcomeYesThe severe outcome, if any. 'none' means no 1904.39 reporting is triggered.
amputation_kindNoFor an amputation only: what kind. 1904.39(b)(11) defines amputation as the traumatic loss of a limb or external body part, and expressly EXCLUDES avulsions, enucleations, deglovings, scalpings, severed ears, and broken or chipped teeth. Fingertip amputations count with or without bone loss, as do medical amputations and parts since reattached. One of: severed_or_cut_off, fingertip_amputation, medical_amputation, reattached_part, avulsion, enucleation, degloving, scalping, severed_ear, broken_or_chipped_tooth, not_applicable.not_applicable
learned_datetimeYesISO 8601 datetime the employer LEARNED of the outcome. Reporting deadlines run from this moment.
outcome_datetimeNoISO 8601 datetime the outcome occurred (e.g. date of death). Used to check the eligibility window (fatality within 30 days of incident; hospitalization/amputation/eye loss within 24 hours). If omitted, the window cannot be verified.
incident_datetimeYesISO 8601 datetime of the work-related incident, e.g. 2026-07-25T09:40:00-05:00.
reporting_exclusionNoWhether a 1904.39(b)(3)-(b)(4) reporting exclusion applies. A motor vehicle accident on a public street or highway is excluded UNLESS it happened in a construction work zone; events on commercial or public transport (airplane, train, subway, bus) are excluded. Either way the event is still RECORDABLE. One of: public_road_motor_vehicle_not_in_work_zone, commercial_or_public_transportation, none.none
hospitalization_for_observation_or_diagnostics_onlyNoFor an in-patient hospitalization only: was the admission for OBSERVATION or DIAGNOSTIC TESTING alone? If so it is not reportable (1904.39(b)(10)) — only admissions for care or treatment are.

Output Schema

NameRequiredDescription
kindYes
valueYes
cfr_citeYes
source_urlYes
last_verifiedYes

TDQS

A4.3/5.0
Behavior4/5

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

The description transparently explains key behavioral rules: exclusions still leave the case recordable, observation-only hospitalizations are not reportable, and specific amputation definitions. It also clarifies that deadlines run from the learned datetime. Annotations already cover safety (read-only, idempotent), so the description adds regulatory context without redundancy.

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

Conciseness4/5

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

The description is detailed but necessary given the regulatory complexity. It is structured logically: purpose, key rules, exclusions, and a disclaimer. While slightly long, every sentence adds relevant information, and it is not redundant with the schema.

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

Completeness4/5

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

The description provides sufficient regulatory context for the tool's operation, including definitions, exclusions, and deadline logic. Since an output schema is present, the lack of explicit return-value explanation is acceptable. The tool appears complete for its intended triage role.

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

Parameters4/5

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

The schema covers 100% of parameters with descriptions, and the tool description reinforces the meaning of each parameter by explaining regulatory context (e.g., amputation_kind definitions, exclusion categories). It adds value beyond the schema by linking parameters to the regulation.

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

Purpose5/5

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

The description clearly states the tool's purpose: determine if reporting is required and compute deadlines for severe outcomes. It uses specific verbs like 'determine' and 'compute' and references the specific regulation (29 CFR 1904.39). It distinguishes itself from general recordability tools by focusing on reporting obligations.

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

Usage Guidelines4/5

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

The description explains when the tool is applicable (severe outcomes) and includes exclusions (e.g., public road accidents, transport). It also notes it is for reference and triage only, not legal advice. However, it does not explicitly contrast with sibling tools, which slightly reduces clarity.

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

osha_classify_300_log_entryClassify OSHA 300 Log Entry (29 CFR 1904.29)A
Read-onlyIdempotent

For a recordable case, determine the correct OSHA 300 Log outcome column (G death, H days away, I job transfer/restriction, J other recordable) using the most-serious-outcome rule, the injury/illness type column, and the day counts capped at 180. Check on_log first — it is false when the case is not recordable. Medical removal cases must be days-away or restricted, never column J, and a removal following a chemical exposure goes in the poisoning column (1904.9(b)(1)); a tuberculosis case goes in the respiratory condition column (1904.11(a)), and may be lined out on the three kinds of evidence 1904.11(b)(2) enumerates. Run osha_assess_recordability first. Reference and triage only.

NameRequiredDescriptionDefault
deathNoDid the injury/illness result in death?
illness_typeNoThe injury/illness type column (M).injury
is_recordableYesIs the case recordable? Run osha_assess_recordability first. If false, it does not go on the 300 Log.
tuberculosis_caseNoIs this a tuberculosis case? 1904.11(a) requires the RESPIRATORY CONDITION column.
days_away_from_workNoCALENDAR days away from work. Do NOT count the day the injury occurred (1904.7(b)(3)(i)). Count calendar days the employee was unable to work regardless of schedule — weekends, holidays and vacation days are included if they could not have worked (1904.7(b)(3)(iv)). If a PLHCP recommended a return date but the employee stayed home, end the count there (1904.7(b)(3)(iii)).
medical_removal_caseNoIs this a medical removal case? 1904.9(b)(1) requires it be entered as EITHER days away OR restricted work depending on how the removal requirement was met — 'other recordable' (column J) is not available.
date_information_receivedNoISO 8601 date the employer RECEIVED information that a recordable case occurred. 1904.29(b)(3) gives 7 calendar days from that moment — not from the incident — to complete both the 300 Log entry and the 301 Incident Report.
days_restricted_or_transferNoCALENDAR days of job transfer or restricted work, counted the same way as days away (1904.7(b)(4)(xi)). Run osha_evaluate_restricted_work first — not every restriction counts. If the employee was permanently reassigned to a job that eliminates the restricted functions, the count may stop when that becomes permanent, but at least ONE day must be counted.
tb_non_occupational_evidenceNoFor a TB case already on the log: evidence that the infection was NOT caused by occupational exposure. 1904.11(b)(2) enumerates three circumstances and permits — does not require — lining out or erasing the entry. One of: household_contact, public_health_department_contact, medical_investigation, none.none
bloodborne_diagnosis_after_recordingNoHas a case already recorded as a needlestick or sharps INJURY since produced a diagnosis of an infectious bloodborne disease? 1904.8(b)(3) then requires the existing entry to be amended rather than a new case recorded — including changing its classification from injury to illness.
medical_removal_from_chemical_exposureNoDid the medical removal follow a CHEMICAL exposure? If so the POISONING column must be checked (1904.9(b)(1)) — set illness_type to 'poisoning'.

Output Schema

NameRequiredDescription
kindYes
valueYes
cfr_citeYes
source_urlYes
last_verifiedYes

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, so the safety profile is clear. The description adds specific behavioral rules: the most-serious-outcome rule, 180-day cap, on_log false for non-recordable, medical removal never column J, chemical exposure → poisoning column, TB → respiratory condition column, and lining out on three kinds of evidence. This is substantial context beyond annotations. It doesn't restate the annotations and adds value on the regulatory logic. Not a 5 because it doesn't address what happens on edge cases like the 7-day completion deadline (though that's in the schema) or failure modes.

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

Conciseness5/5

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

The description is a dense but well-structured paragraph: opens with the decision target, then the key rule, then the on_log gate, then the two special-column rules, and closes with the prerequisite and a triage note. No wasted words. It front-loads the most critical info (the classification rule) before regulatory details.

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

Completeness4/5

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

The tool has 11 parameters, a rich output schema, and a complex regulatory domain. The description ties into the prerequisite tools and gives enough context to invoke correctly: what to check first, when not to use (on_log false, medical removal not J), and special cases. It could go deeper on the interaction with e.g. osha_evaluate_restricted_work for the restricted-days counting, or clarify the refusal of the 180-day cap on the day counts, but it covers the major decisions. Given the output schema exists, not explaining return format is acceptable. 4 is fair.

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

Parameters3/5

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

Schema description coverage is 100%, so the schema thoroughly documents every parameter. The tool description itself doesn't expand on individual parameters, but it does compound the regulatory logic: e.g., it mentions the medical-removal rule and the chemical-exposure/poisoning link that ties to the medical_removal_from_chemical_exposure and medical_removal_case parameters, and notes the TB/gas evidence that maps to tb_non_occupational_evidence. That gives the parameters regulatory meaning beyond the schema's own text, which is already rich. I'd give 3—the schema carries most of the weight, but the description adds some regulatory interrelations.

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

Purpose5/5

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

The description states a specific verb ('determine the correct OSHA 300 Log outcome column'), names the exact resource (OSHA 300 Log column G/H/I/J), and explains the selection rule (most-serious-outcome, injury/illness type, day counts capped at 180). It clearly distinguishes this tool from siblings like osha_assess_recordability and osha_evaluate_restricted_work, which are mentioned as prerequisites.

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

Usage Guidelines5/5

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

The description explicitly instructs 'Run osha_assess_recordability first' and mentions 'Check on_log first' for non-recordable cases. It also references osha_evaluate_restricted_work for days restrictions in the parameter description, and 'Reference and triage only' clarifies this is a classification tool, not one that creates or modifies records. It clearly scopes when to use this tool versus when to use the assess/evaluate siblings.

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

osha_determine_recording_employerDetermine Which Employer Records the Case (29 CFR 1904.31)A
Read-onlyIdempotent

Decide WHOSE OSHA 300 Log a case belongs on when the injured person is not a straightforward payroll employee — a temp, a leased or supplied worker, a contractor's employee, someone self-employed, or an owner. Run this FIRST whenever the injured person is not on the employer's payroll: if the answer is 'the other employer' or 'no one', the rest of the chain is not this employer's obligation. The controlling test is DAY-TO-DAY SUPERVISION, not who issues the paycheck (1904.31(b)(2)-(b)(3)): a temp on an agency's payroll whose work you direct daily is your case to record. Self-employed people are not covered by the OSH Act at all (b)(1)), and owners or partners of a sole proprietorship or partnership are not employees for recordkeeping (a)). Every payroll category counts — part-time, seasonal and migrant workers included. 1904.31(b)(4) requires the case be recorded exactly once, never on both employers' logs. Reference and triage only — not legal advice.

NameRequiredDescriptionDefault
worker_relationshipYesThe injured person's relationship to the employer asking. One of: on_your_payroll, temporary_leased_or_supplied, contractor_employee, self_employed, owner_or_partner. Note 'on_your_payroll' covers every category — labor, executive, hourly, salary, part-time, seasonal and migrant workers all count (1904.31(a)).
you_supervise_day_to_dayNoDo YOU supervise this worker's work on a day-to-day basis? This is the controlling test for temporary, leased, supplied and contractor workers — not who issues the paycheck. Irrelevant for payroll employees, the self-employed, and owners or partners.

Output Schema

NameRequiredDescription
kindYes
valueYes
cfr_citeYes
source_urlYes
last_verifiedYes

TDQS

A4.8/5.0
Behavior5/5

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

The description fully discloses the decision logic, including the day-to-day supervision test and the irrelevance of paycheck issuer for temporary workers. It also references specific OSHA regulations (1904.31(a), (b)(1)-(b)(4)) and notes that it is not legal advice, which sets appropriate expectations. No contradictions with the readOnlyHint and idempotentHint annotations.

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

Conciseness4/5

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

The description is a bit lengthy but well-structured with clear sentences addressing different aspects (purpose, when to use, controlling test, exclusions, and legal reference). It avoids unnecessary fluff, though some points are repeated across the description and parameter descriptions.

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

Completeness5/5

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

The description provides comprehensive context for the decision process, including the rule for temporary workers and the exclusion of self-employed and owners. It also mentions that the case must be recorded only once (1904.31(b)(4)), making it complete for the tool's intended use within the OSHA recording workflow.

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

Parameters4/5

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

The schema already provides descriptions for both parameters, but the overall description adds meaningful context, such as clarifying that 'on_your_payroll' covers all employee types and that supervision is irrelevant for payroll employees. This enriches understanding beyond the schema's individual descriptions.

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

Purpose5/5

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

The description clearly states the tool's purpose: determining which employer records a case on their OSHA 300 Log for non-payroll workers. It lists specific categories (temp, contractor, self-employed, owner) and the controlling test (day-to-day supervision), distinguishing it from sibling tools like assess_work_relatedness or evaluate_restricted_work.

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

Usage Guidelines5/5

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

It explicitly instructs to run this tool first whenever the injured person is not on the employer's payroll, and explains that if the outcome is 'the other employer' or 'no one', the rest of the chain is not this employer's obligation. This provides clear when-to-use guidance and differentiates from later steps in the recordability assessment chain.

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

osha_evaluate_hearing_lossEvaluate Occupational Hearing Loss (29 CFR 1904.10)A
Read-onlyIdempotent

Compute whether an audiogram produces a recordable hearing loss. Two tests must BOTH be met and, critically, in the SAME ear: a Standard Threshold Shift of 10 dB or more averaged at 2000, 3000 and 4000 Hz against the employee's baseline (1904.10(b)(1)), and a total hearing level of 25 dB or more above audiometric zero on the current audiogram (1904.10(a)). An STS in one ear and a 25 dB level in the other does not record. Pass raw audiogram values and the tool does the arithmetic — do not compute averages yourself. If the employee has had a prior recordable hearing loss, pass the REVISED baseline (b)(2)(i)). Age adjustment from Tables F-1/F-2 of 1910.95 appendix F applies to the STS test only, never to the 25 dB test (b)(3)). A retest within 30 days that does not confirm the STS defeats the case; one that confirms it starts a 7-day recording clock (b)(4)). A PLHCP determination of no work-relatedness ends it entirely (b)(6)). Reference and triage only — not legal advice.

NameRequiredDescriptionDefault
retest_dateNoISO 8601 date of a confirming retest. Used to compute the 7-calendar-day recording deadline (1904.10(b)(4)).
current_leftYesLEFT ear current audiogram.
baseline_leftYesLEFT ear baseline audiogram. If the employee has previously had a recordable hearing loss, use the REVISED baseline reflecting that case, not the original (1904.10(b)(2)(i)).
current_rightYesRIGHT ear current audiogram.
baseline_rightYesRIGHT ear baseline audiogram, or the revised baseline if a prior hearing loss was recorded.
retest_confirmed_stsNoIf retested, did the retest CONFIRM the recordable STS? A retest within 30 days that does not confirm it means the case need not be recorded.
age_adjustment_db_leftNoOptional dB age correction for the LEFT ear, derived from Tables F-1/F-2 of 29 CFR 1910.95 appendix F. Applies ONLY to the STS test — it may NOT be applied to the 25 dB total-hearing-level test (1904.10(b)(3)). The tool does not compute this; supply it from the tables or leave 0.
age_adjustment_db_rightNoOptional dB age correction for the RIGHT ear. Same rules as the left.
retested_within_30_daysNoWas the employee's hearing retested within 30 days of the first test? (1904.10(b)(4))
plhcp_determined_not_work_relatedNoHas a PLHCP determined, applying 1904.5, that the hearing loss is not work-related or that occupational noise did not significantly aggravate it? If so the case need not be recorded (1904.10(b)(6)).

Output Schema

NameRequiredDescription
kindYes
valueYes
cfr_citeYes
source_urlYes
last_verifiedYes

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false. The description adds substantial behavioral context: the two tests must be met in the same ear, age adjustment applies only to the STS test, retest rules (30-day window, confirmation vs. non-confirmation), and the PLHCP determination ending the case. It also warns that the tool does arithmetic and the user must supply age adjustments. This rich disclosure goes well beyond the annotations and precisely explains the decision logic.

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

Conciseness5/5

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

Though long, every sentence carries unique regulatory detail. The main purpose is front-loaded, and the subsequent sentences each clarify a distinct condition or exception. The structure uses parentheses for references and enumerations, making it scannable. There is no redundancy or filler; the length is justified for the regulatory complexity.

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

Completeness5/5

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

With 10 parameters, nested objects, and an output schema present, the description covers all essential behavioral aspects: the two decision tests, same-ear requirement, age adjustment scope, retest logic, PLHCP override, and usage constraints. It also includes a disclaimer about legal advice. The output schema handles return values, so that gap is not an issue. For a complex OSHA evaluation tool, this description is thoroughly complete.

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

Parameters5/5

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

Schema description coverage is 100%, so a baseline of 3 applies. The description adds meaning beyond the schema by clarifying relationships: it explains the same-ear condition, that baseline values should be the revised baseline when applicable, and that age adjustments are for STS only. It instructs the agent to pass raw values and not precompute averages, and clarifies the interplay between retest flags and the PLHCP flag. This adds semantic depth that the schema alone does not provide.

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

Purpose5/5

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

The description opens with a precise verb and resource: 'Compute whether an audiogram produces a recordable hearing loss.' It also specifies the regulatory basis (29 CFR 1904.10) and the two tests, making it unmistakable from sibling tools that handle other OSHA recordkeeping aspects. The purpose is specific, actionable, and distinguishes this tool from the broader osha_assess_recordability and similar siblings.

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

Usage Guidelines4/5

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

The description gives clear context and instructions: 'Pass raw audiogram values and the tool does the arithmetic — do not compute averages yourself,' and explains when to pass a revised baseline. It also disclaims 'Reference and triage only — not legal advice.' However, it does not explicitly name sibling tools or state when NOT to use this tool (e.g., for work-relatedness determination, use osha_assess_work_relatedness). Since the domain is specific, the exclusion is implicit but not explicit, so a 4 is appropriate.

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

osha_evaluate_restricted_workEvaluate Restricted Work or Job Transfer (29 CFR 1904.7(b)(4))A
Read-onlyIdempotent

Decide whether a work restriction or job transfer actually counts as restricted work — not every restriction does. Run this BEFORE passing 'restricted_work_or_transfer' as an outcome to osha_assess_recordability, because getting it wrong moves cases onto or off the 300 Log. The rules it applies: a restriction confined to the day of injury does not count (b)(4)(iii); reduced output while still doing all routine functions does not count (b)(4)(vi); a restriction that misses every routine function does not count (b)(4)(iv), where routine functions are activities performed at least once per week (b)(4)(ii); a partial shift does count (b)(4)(v); and a job transfer is recorded in the same column (b)(4)(ix)-(x)). Critically, when a vague recommendation such as 'light duty' cannot be clarified with the PLHCP, the case MUST be recorded as restricted work (b)(4)(vii)) — the regulation resolves that doubt toward recording. Reference and triage only — not legal advice.

NameRequiredDescriptionDefault
reduced_output_onlyNoIs the ONLY effect that the employee produces less while still performing all routine functions and working the full shift? That is not restricted work (1904.7(b)(4)(vi)).
restriction_is_vagueNoIs the recommendation vague — 'light duty', 'take it easy for a week' — rather than specific? (1904.7(b)(4)(vii))
worked_partial_shiftNoDid the employee work only part of a shift because of the injury or illness? A partial day counts as a day of restriction or transfer, except on the day of the injury (1904.7(b)(4)(v)).
transferred_to_another_jobNoWas the employee assigned to a job other than their regular job for part of the day? Transfers are recorded in the same 300-Log box as restricted work (1904.7(b)(4)(ix)-(x)).
vague_restriction_clarifiedNoIf the restriction was vague, was the PLHCP successfully asked whether the employee can do ALL routine functions AND work the FULL shift? If clarification could NOT be obtained, pass false — 1904.7(b)(4)(vii) then requires the case to be recorded as restricted work.
restriction_applies_beyond_day_of_injuryYesDoes the restriction or transfer extend beyond the day the injury occurred or the illness began? A restriction imposed ONLY for that day is not recordable as restricted work (1904.7(b)(4)(iii)).
keeps_from_routine_function_or_full_shiftYesDoes the restriction keep the employee from one or more ROUTINE functions, or from working the full workday they would otherwise have been scheduled? Routine functions are activities the employee regularly performs AT LEAST ONCE PER WEEK (1904.7(b)(4)(ii)). A restriction on something done less often than weekly is not a restriction on a routine function.

Output Schema

NameRequiredDescription
kindYes
valueYes
cfr_citeYes
source_urlYes
last_verifiedYes

TDQS

A4.3/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the description does not need to repeat those. It does add valuable behavioral context beyond the annotations: the tool applies a decision tree based on regulation, and it emphasizes the doubt-resolution rule that vague recommendations default to recording. It also notes the tool is not legal advice, which is a helpful behavioral caveat. There is no contradiction with annotations.

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

Conciseness4/5

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

The description is long, but it packs a dense set of regulatory rules that are essential for correct usage. It front-loads the purpose and usage instruction ('Run this BEFORE...'), then lists the key rules in a structured sequence. While it could be slightly trimmed, the length is justified by the complexity of the regulatory domain. It is not tautological or redundant with the title.

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

Completeness4/5

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

Given the complexity of the tool (7 parameters, complex decision rules, and an output schema), the description provides sufficient context: it explains the decision criteria, the critical vague-restriction rule, and the tool's place in the workflow. Since an output schema exists, the description need not describe return values. The only minor gap is that it does not explicitly state the ternary nature of the output (true/false/unknown), but the output schema presumably covers that. It is complete enough for an agent to understand when and how to invoke it correctly.

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

Parameters3/5

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

Schema description coverage is 100% — every parameter has a detailed description including regulatory references (e.g., '1904.7(b)(4)(iii)' for restriction confined to day of injury). The description itself does not elaborate on individual parameters, but that is unnecessary given the schema's thoroughness. The description does add context about the overall decision logic, but it does not go beyond what the schema already explains for each parameter. Baseline 3 is appropriate.

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

Purpose5/5

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

The description clearly states the specific action: 'Decide whether a work restriction or job transfer actually counts as restricted work'. It immediately differentiates itself from siblings by mandating that it runs BEFORE passing 'restricted_work_or_transfer' to osha_assess_recordability, and it lists the exact regulatory references (29 CFR 1904.7(b)(4) subsections). This is a specific verb+resource with explicit sibling differentiation.

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

Usage Guidelines5/5

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

Usage is precisely defined: 'Run this BEFORE passing restricted_work_or_transfer as an outcome to osha_assess_recordability'. It also enumerates what does and does not count as restricted work, including the critical caveat about vague restrictions that must be recorded unless clarified. It further warns that it is 'Reference and triage only — not legal advice,' setting clear boundaries for its use.

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

osha_route_to_establishment_logRoute a Case to the Right Establishment Log (29 CFR 1904.30)A
Read-onlyIdempotent

Decide WHICH establishment's OSHA 300 Log a recordable case belongs on — the last question about an individual incident, and one multi-site employers routinely get backwards. Under 1904.30(b)(4) the case follows the PLACE, not the person: an injury occurring at one of the employer's establishments is recorded on THAT establishment's log even when the employee normally works elsewhere, while an injury away from all of them (a customer site, in transit, remote work) goes on the log of the establishment where the employee normally works. Also reports whether the destination needs its own log — required for establishments expected to operate a year or longer (1904.30(a)), optional for short-term sites which may share a combined log (b)(1) — and, when records are kept centrally, the 7-calendar-day transmission deadline and the two conditions central recordkeeping depends on (b)(2)). Reference and triage only — not legal advice.

NameRequiredDescriptionDefault
records_kept_centrallyNoAre the establishment's records kept at headquarters or another central location? Permitted only on the two conditions in 1904.30(b)(2).
date_information_receivedNoISO 8601 date the employer received information that a recordable case occurred. Used with central recordkeeping to compute the 7-calendar-day transmission deadline (1904.30(b)(2)(i)).
employee_was_telecommuting_from_homeNoWas the employee working from home at the time? A home is NEVER a business establishment and needs no separate 300 Log (1904.46(3)) — the case goes on the log of the establishment the telecommuter is linked to under 1904.30(b)(3). Pass false for occurred_at_one_of_your_establishments in this case.
occurred_at_one_of_your_establishmentsYesDid the injury or illness occur AT one of the employer's own establishments? True even if it is not the employee's usual site. False for a customer site, in transit, or working from home. An establishment is a single physical location where business is conducted (1904.46); for mobile work — construction, transportation, utilities — it is the office, terminal or station that supervises the activity or is the base for it.
destination_expected_to_operate_a_year_or_longerNoIs the establishment whose log will carry the case expected to be in operation for a year or longer? If not, no separate log is required — its cases may go on a combined short-term log, optionally per division or geographic region (1904.30(a), (b)(1)).

Output Schema

NameRequiredDescription
kindYes
valueYes
cfr_citeYes
source_urlYes
last_verifiedYes

TDQS

A5/5.0
Behavior5/5

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

Annotations indicate readOnlyHint=true, idempotentHint=true, destructiveHint=false, and the description fully aligns with these. It goes beyond annotations by elaborating the regulatory framework and edge cases (e.g., telecommuting, mobile work, short-term establishments), providing transparency about the tool's decision-making behavior without contradiction. No side effects are implied, consistent with read-only nature.

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

Conciseness5/5

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

While lengthy, the description is well-structured and information-dense. It front-loads the core purpose and then systematically explains the decision logic, referencing specific regulations and edge cases. Every sentence adds value, and the regulatory citations (1904.30(a), (b)(1)-(4), 1904.46) are precise. No redundancy or filler is present.

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

Completeness5/5

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

Given the complexity of OSHA regulations, the description is remarkably complete. It covers the main rule (place of injury), exceptions (telecommuting, mobile work), and ancillary considerations (short-term establishments, central recordkeeping deadlines). Since an output schema exists, the lack of explicit return-value description is acceptable. The description equips an agent to make the correct routing decision without ambiguity.

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

Parameters5/5

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

Schema coverage is 100% with all 5 parameters described in detail. The description adds semantic depth by explaining the significance of each parameter (e.g., 'occurred_at_one_of_your_establishments' definition includes mobile work nuances, and 'employee_was_telecommuting_from_home' clarifies that a home is never an establishment). This exceeds the schema's basic descriptions and provides the rationale for parameter values.

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

Purpose5/5

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

The description clearly states the tool's purpose: to decide which establishment's OSHA 300 Log a recordable case belongs on. It uses a specific verb ('Decide') and a specific resource ('establishment's OSHA 300 Log'), and it distinguishes itself from sibling tools like check_recordkeeping_obligation and determine_recording_employer by focusing on the final routing decision.

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

Usage Guidelines5/5

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

The description explicitly positions this as 'the last question about an individual incident,' making clear it is used after other recordability steps. It also provides detailed regulatory context (1904.30(b)(4)) and explains the decision logic, effectively guiding when to use this tool versus alternatives. The 'last question' phrasing implies it's the final step in a sequence, which is sufficient for routing.

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

Tool Schema Changelog

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

  1. 11 tool updatesv0.1.0
    • First observedosha_assess_new_case
    • First observedosha_assess_recordability
    • First observedosha_assess_work_relatedness
    • First observedosha_check_privacy_case
    • First observedosha_check_recordkeeping_obligation
    • First observedosha_check_severe_injury_reporting
    • First observedosha_classify_300_log_entry
    • First observedosha_determine_recording_employer
    • First observedosha_evaluate_hearing_loss
    • First observedosha_evaluate_restricted_work
    • First observedosha_route_to_establishment_log

TDQS

A4.4/5.0

Scored across 11 tools

Disambiguation4/5

Each tool maps to a distinct, named regulatory decision point in the Part 1904 pipeline, and the cross-references ('Run this BEFORE...') make the flow clear. However, there is residual ambiguity risk: 'assess' tools (work_relatedness, new_case) are near-synonyms for 'evaluate' tools (restricted_work, hearing_loss), and an agent could initially hesitate between osha_assess_recordability and its sub-tools despite the explicit guidance. The two 'check' obligation gates are also conceptually parallel, though the domain separation is real.

Naming Consistency4/5

All tool names follow a uniform snake_case `osha_<verb>_<object>` pattern, and the object nouns are clear and meaningful. However, the verb choices — assess, evaluate, check, determine, classify, route — are largely interchangeable near-synonyms that follow a subtle internal logic (check=obligation gates, assess=decision nodes, evaluate=sub-computations) that is not self-evident from the names alone. The pattern is consistent but the verb selection is slightly muddier than a strict verb_noun taxonomy.

Tool Count5/5

With 11 tools, the server is well within the ideal 3-15 range for a domain as broad as Part 1904 recordkeeping. Each tool earns its place by covering a genuine regulatory gate, and the count feels appropriately granular — not so few that decisions are conflated, not so many that the surface becomes unmanageable. The split of the 1904.4 decision tree into discrete tools is justified by the complexity of each step.

Completeness4/5

The end-to-end recordkeeping lifecycle is thoroughly covered: threshold obligation → employer attribution → work-relatedness → new case → recordability → classification → privacy → establishment routing, plus severe-injury reporting. Notable gaps include the 300A annual summary and posting requirement, employee/authorized-representative access to records, and corrections to already-filed logs, but these are administrative follow-ons rather than core decision dead-ends. The coverage of 1904.8-1904.12 specific-case criteria is also mostly folded into the broader tools.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI agents to perform security alert triage by ingesting raw logs, extracting IOCs, querying threat intelligence sources, and generating structured NIST/MITRE assessments with reasoning traces.
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables users to trace regulatory rule changes to affected parties and required actions through deterministic safety gates, returning dated action plans and hash-linked evidence records. Supports 12 MCP tools over stdio or streamable HTTP for source comparison, obligation decomposition, scope assessment, planning, and evidence validation across multiple domain packs.
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    Enables local, deterministic clinical calculations for nursing and emergency care, including Parkland formula, body surface area, and IV drip rate tools with validated typed inputs.
    3
    MIT