Skip to main content
Glama
srhtdmrkl

osha-recordkeeping-mcp

by srhtdmrkl

OSHA Recordkeeping MCP — 29 CFR Part 1904

안전 관리자가 누군가 다쳤을 때마다 마주하는 질문에 답하는 데 도움을 주는 결정론적 Model Context Protocol 서버: 이 사건은 OSHA 기록 대상인가?

11개의 도구가 누군가 다침부터 올바른 로그 항목까지 하나의 사건을 따라가며, 각각 모델의 규정 기억이 아닌 인용된 판정을 반환합니다. MIT 라이선스이며 무료로 사용할 수 있습니다.

참고 및 분류 전용 — 법적 자문이 아니며 의학적 판정도 아닙니다. 모든 판정에는 CFR 인용과 기초 데이터가 eCFR에 대해 마지막으로 검증된 날짜가 포함되어 있어, 추론이 단언이 아닌 감사 가능한 형태로 제공됩니다.

사용 방법

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

그런 다음 Claude Desktop의 claude_desktop_config.json에 추가합니다:

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

nvm을 사용하는 경우 node 바이너리의 절대 경로를 사용하세요 — Claude Desktop은 셸 프로필을 소싱하지 않으므로 단순한 node는 해석되지 않습니다.

동반 Skill은 절차를 담고 있습니다: 체인이 적용되는 시점, 호출 전에 확립해야 할 사항, 그리고 도구가 결정할 수 없는 사항.

Related MCP server: Quellgeist

이 도구가 존재하는 이유

29 CFR Part 1904에 따른 업무상 부상 기록 가능성 평가는 모든 사건에서 발생합니다. 잘못된 판정은 직접적인 규정 준수 위험을 수반합니다: 과다 기록은 총 기록 대상 사고율(TRIR)을 인위적으로 부풀리고, 과소 기록은 29 CFR 1904.4에 따라 OSHA 인용을 초래합니다.

Part 1904에 따른 기록 가능성은 여러 독립적 트리거를 평가합니다: 일반 기준(사망, 이탈 일수, 업무 제한, 의식 상실, 1904.7에 따른 PLHCP 진단), 특정 사례 규칙(바늘 찔림, 의학적 제거, 청력 손실, 1904.8–1904.12에 따른 결핵), 그리고 치료 분류. 치료의 경우 1904.7(b)(5)(ii)는 응급 처치 치료의 폐쇄된 14개 항목 열거 목록을 정의합니다. 이러한 폐쇄된 규제 규칙을 타입화된 도구 내에서 구현하면 규제 텍스트에 대한 LLM 보간을 재현 가능한 조회 논리로 대체합니다.

작업 분담: LLM이 서술하고 도구가 결정합니다

호출 모델은 자신이 잘하는 일을 합니다 — 지저분한 사건 서술을 읽고 이를 표준 코드(치료 유형, 결과)에 매핑합니다. 도구는 모델이 법적 판정을 위해 해서는 안 되는 일을 합니다 — 폐쇄된 목록을 결정론적으로 적용하고 인용된 답변을 반환합니다. 도구는 자유 텍스트 치료 설명을 절대 받지 않습니다. 판정이 재현 가능하도록 통제된 어휘만 받습니다.

앵커 도구: osha_assess_recordability

입력. 모델은 서술을 다음 항목에 매핑합니다. 자유 텍스트는 절대 전달하지 않습니다.

필드

의미

work_related

1904.5 — osha_assess_work_relatedness에서 공급, 여기서 판단하지 않음

new_case

1904.6 — 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

1904.8-1904.12 트리거 — 바늘 찔림, 의학적 제거, 청력 손실, 결핵, 진단이 있는 혈액 매개 노출

plhcp_recommendations_not_followed

직원이 무시했더라도 권고가 구속력을 갖는 세 가지 경우 (1904.7(b)(3)(ii), (b)(4)(viii), (b)(5)(v))

medical_removal_was_voluntary_and_early

1904.9(b)(3) 가드 — 조기 철수는 기록 대상이 아님

tuberculosis_test_was_pre_employment

1904.11(b)(1) 가드 — 채용 신체검사 양성은 업무상이 아님

treatments

통제된 코드. 응급 처치 코드는 폐쇄된 목록에서 오며, 두 코드는 응급 처치도 의학적 치료도 아님 (1904.7(b)(5)(i))

처음 세 배열은 필수이며 의도적입니다. 기본값 []*"확인했고 없음"*과 구분할 수 없으므로, 기본값을 두면 불충분하게 명시된 서술이 자신 있는 인용된 위음성(false negative)을 반환할 수 있습니다 — 인용을 유발하는 과소 기록 방향입니다.

출력. 값에 recordable, basis, triggering_factors(각각 자체 하위 조항 인용 포함), 1904.39가 적용될 수 있을 때 severe_injury_reporting_note, 기준이 로그 자체에 부과하는 결과에 대한 log_entry_notes, 그리고 아무것도 단언되지 않았을 때 under_specified를 담는 RuleRecord. 등록 계층은 determination_finalclarification_required를 추가합니다 — 아래 Elicitation 참조.

판정 논리(결정론적) — 1904.4(b)(2) 결정 트리 순서:

  1. work_related가 false이면 → 기록 대상 아님 (1904.5).

  2. new_case가 false이면 → 새 항목 없음, 단 일수나 결과가 변경된 경우 기존 항목을 업데이트 (1904.6). 트리는 여기로 라우팅되며 단순히 멈추지 않습니다.

  3. 그 외 specific_case_criteria가 있으면 → 기록 대상 (1904.8-1904.12), 응급 처치 목록을 전혀 참조하지 않음.

  4. 그 외 outcome이 있으면 → 기록 대상 (일반 기록 기준, 1904.7(b)(1)).

  5. 그 외 significant_diagnosis가 있으면 → 응급 처치만 제공되었더라도 기록 대상 (1904.7(b)(7)).

  6. 그 외 treatment가 폐쇄된 응급 처치 목록에 없으면기록 대상 (응급 처치를 넘는 의학적 치료, 1904.7(b)(5)(i)).

  7. 그 외 → 기록 대상 아님 (응급 처치만 있고 특정 사례 기준 없음).

3단계가 존재하는 이유는 1904.4(a)(3)**분리(disjunction)**이기 때문입니다: 1904.7 또는 1904.8-1904.12의 특정 사례. 이것이 없으면 세척과 붕대로 처리된 오염된 바늘 찔림이 인용과 함께 "기록 대상 아님"으로 반환되었을 것입니다 — 같은 서버의 개인정보 도구가 이를 개인정보 사례로 올바르게 분류한 반면에. 응급 처치 목록을 전혀 참조하지 않는 기록 기준은 목록 이후가 아니라 이전에 확인되어야 합니다.

프로토콜 표면(세 가지 MCP 프리미티브 모두)

이 서버는 Tools뿐만 아니라 전체 프로토콜을 사용합니다:

  • Tools — 아래 사건 분류 체인에 나열된 11가지 판정. 각각 outputSchema를 선언하고 JSON 문자열이 아닌 타입화된 structuredContent를 반환하며, 각각 readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false로 주석 처리되어 있습니다 — 안전하고, 재시도 가능하며, 순수 조회입니다.

  • Resources — 15개 데이터셋 모두 직접 노출되므로 클라이언트는 도구 호출을 통해서만이 아니라 참조 데이터를 컨텍스트로 로드할 수 있습니다. 데이터 모델이 제품이며, Resources가 이를 보이게 만듭니다. URI는 osha://data/<id>이며, 여기서 <id>src/datasets.ts의 키입니다 — 예: osha://data/first-aid-treatments, osha://data/partially-exempt-industries, osha://data/privacy-cases.

  • Prompttriage_incident는 단일 사용자 호출 워크플로우로 하나의 사건을 전체 체인을 통해 진행합니다: 범위 → 기록 고용주 → 업무 관련성 → 새 사건 → 업무 제한 → 청력 손실 → 기록 가능성 → 보고 기한 → 300-Log 열 → 개인정보 사례 → 사업장.

  • Elicitationosha_assess_recordability는 추측해서는 안 되는 하나의 경계 사례를 해결합니다: OTC vs. 처방 강도 약물. 비처방 강도는 응급 처치이고, 처방 강도는 의학적 치료이며 기록 대상입니다. 서술이 침묵하면 모델은 medication_unspecified_strength를 전달하고 강도는 도구가 선택하는 것이 아니라 사람에게 물어서 해결됩니다.

    2단계 해결. Elicitation은 선택적 MCP 기능이므로 서버는 getClientCapabilities()를 확인하고 채널을 선택합니다:

    클라이언트가 elicitation 광고

    채널

    결과

    서버가 사용자에게 직접 프롬프트

    단일 도구 호출로 해결

    아니요

    determination_final: false + clarification_required 반환

    모델이 채팅에서 물어본 후 해결된 코드로 재호출

    어느 쪽이든 질문은 사람에게 도달하며 도구는 절대 추측하지 않습니다. 잠정 결과는 보수적으로 유지됩니다 — recordable: true, 근거는 확인 대기 중으로 표시 — 그리고 clarification_required는 질문, CFR 사유, 각 답변에 대해 다시 보낼 정확한 치료 코드를 담습니다.

    특정 클라이언트가 어느 단계에 속하는지는 가정보다 확인할 가치가 있습니다. 여기서 검증됨: Claude Desktop의 채팅 클라이언트는 elicitation 기능을 광고하지 않으며, MCP Inspector 0.15.0과 1.0.0도 마찬가지입니다. 에이전트 클라이언트는 다를 수 있으며, 자체 메커니즘으로 사용자에게 묻는 클라이언트는 외부에서 동일해 보입니다. 서버는 연결 시 elicitation=supported|NOT supported를 stderr에 기록합니다 — 어떤 클라이언트에서든 시작하고 해당 줄을 읽으세요.

출처 및 강제된 만료

RuleRecord<T>( src/types.ts 참조)는 규제 규칙을 담습니다: cfr_cite, source_url, last_verified, 그리고 eCFR이 제공하는 경우 amendment_historyeditorial_note. effective_date 필드는 없습니다. 데이터셋은 현재 eCFR 텍스트를 담고 있으며, last_verified는 규제 검증 날짜를 나타냅니다.

만료는 scripts/check-decay.ts를 통해 강제되며, 레코드의 last_verified가 만료 임계값을 초과하면 빌드가 실패합니다. 푸시 시와 주간 CI 일정으로 실행되며, 하위 부분 source_url 대상을 검증하고 eCFR editorial_note 항목을 확인합니다.

사건 분류 체인(제공됨)

"누군가 다침"부터 올바른 로그 항목까지 하나의 사건을 따르는 11가지 결정론적 도구:

  1. osha_check_recordkeeping_obligation (1904.1, 1904.2) — 다른 모든 판정이 전제로 삼는 질문: 이 고용주는 애초에 기록을 유지해야 하는가? 규모 면제는 지난 연도의 최대 고용 인원을 기준으로 회사 전체에 걸쳐 측정한다 — 평균도, 특정 사업장만도 아니다. 업종 면제는 **사업장(establishment)**에 붙어 있으며, 이 도구는 NAICS 코드가 주어지면 폐쇄된 82개 코드 Appendix A 목록과 대조해 판정한다. 둘 다 부분적이다: 1904.39 중대 부상(severe-injury) 보고는 어느 쪽의 면제에서도 살아남는다 — 면제 대상 고용주가 위험하게 오인하는 바로 그 점이다니란.

  2. osha_determine_recording_employer (1904.31) — 절차 단계가 아니라 출발점이 되는 질문이다: 부상당한 사람이 급여명부(payroll)에 없다면, 그 사건은 애초에 그 사업주의 사건인가? 급여가 아니라 매일의 감독(day-to-day supervision)이 결정한다. 파견회사의 급여명에 있는 임시 인력이라도, 그 사람의 업무를 당신이 매일 지시한다면 그 사건은 당신이 기록한다; 같은 임시 인력이 파견회사의 감독 아래에 있다면 기록하지 않는다. 자영업자는 OSH Act의 적용 대상 자체가 아니며, 개인사업체(sole proprietorship)의 모든 소유주나 파트너는 기록유지 목적상 직원이 아니다. (b)(4)는 사건을 정확히 한 번만 기록하도록 — 결코 두 로그에 동시에 기록하지 않도록 — 요구한다.

  3. osha_assess_work_relatedness (1904.5) — 다른 모든 것이 의존하는 결제, 그리고 그때까지 이 프로젝트가 모델에게 맡긴 유일한 법적 판단하나였니다. 1904.5(a)는 업무환경에서 발생한 것이다. 무엇이든 지에 업무상 재해(work)와의)도록 추정한다; 1904.5(b)(2)는 그 추정을 반로할 수 있는 9가지 예외의 폐쇄적 목록이다. 판정은 의도적으로 3값(삼가)work_related, not_work_related, requires_judgment — 을 쓴다. 1904.5는 무엇을 규정에 자체가 고용유의 판단에 맡겼기 때문이다: 원인이 불분현한 사고(1904.5(b)(3)), 출장 상태(b)(6), 재택 근무(b)(7), 그리고 어늘 모든예외가 의존하는 "오직(solely)" 판정. 이것들을 하나의 불리언으로 강요하는 것은 .5 Part 1904에서 가장 다툼이 많은 판단들을 도구가 임의 추측하는 꼴이다. 또 인간 전능 을 뒤집어 기억하기 쉬운 두 경우를 단호히 정정해 주기도 한다. 회사 건물 부지에서 통근 중의 자동차 사고 는 (b)(2)(vii)의 예외에 해당하지만, 같은 부지에서 미끄러져 넘어진 슬립·액세스는 어떤 예외인 것을 향지 못한 채 업무관계로 남는다. 그리고 정신질환은 이 방향이 뒤집는다 — 기간 외출하는 것도 아니다. 그 직원이 PLHCP의 소견을 스스로 제시하지 않는 한(b)(2)(ix).

  4. osha_assess_new_case (1904.6) — 새 300 로그 항목을 작성할 것인가, 아니면 이미 있는 항목을 업데이트할 것인가? 즉 1904.4(a)의 논리곱(AND) 가운데 두 번째 조건이다. 이 도구는 규정이 의도적으로 분리하는 재발 사례의 유형을 구분한다. 즉 업무 장에서의 근골에 출한의 범행이 원인이 되는 발현은 신규 사건이다(b)(2) — 예를들면 생산 라인에서 발현된 직업성 천식 — 반면, 노출 되면 없는 채로 증상이 다시 발생하는 만성 질환은 한 번만 기억되어요(b)(1). 유의할는점 (b)(1)는 폐쇄 목록이 아니다: 규정은 암, 섀먼 진단, 직업청 질환, 규폐증을 "예시 일 수 있다(may include)"고만 한다. 따라서 이 도구는 질병 이름 단치가 아니라 상태의 성질을 묻는다. 그리고 이 도구는 이 서버에서 외부 권위자에게 따라가는 유일한 도구하기도 한다. (b)(3)에 따르면 고용주는 PLHCP(직업적정 건강검진가)를 상담해야 할 의무는 없지만, 상담 받았다면 그 권고를 반드시 따라야 한다 — 따라서 PLHCP의 소견은 규칙 로직 전체에 우상하며, 상의하는 소견들이 가 있다면 requires_judgment를 돌려준다. 그것은 두 소견의 가중치를 판단하는 것이 명시적으로 사업주의 책무이기 때문이다.

  5. osha_evaluate_restricted_work (1904.7(b)(4)) — 제한이 정말 집계 대상이 되어도 될까? 모든 제한이 있는 않는, 일이며 그 양쪽 방향의 오류 — 모두 기록을 넣거나 빼는 방향으로 균열하다. 부상 당일만 제한이 국한되는 경우는 집계되지 않는다(b)(4)(iii)); 모든 일상적 기능을 수행하면서 산출량과 목조락는 경우도 집계되지 않는다(b)(4)(vi); "일상의 기능(routine functions)"은 적어도 주 1회 수행하는 활동을 뜻한다(b)(4)(ii)). 부분 교대(partial strength)는 집계된다(b)(4)(v)), 부서 전환이라면 제한 작업 열을 함께 누락시킨다(b)(4)(x)). 그런데 가장 흥미로운 조항은 (b)(4)(vii)이다: "경근의(light duty)"처럼 모호한 권고를 PLHCP가 명확히 해주지 못하는 경우에는, 해당 사건을 반드시 제한된 작업(restricted work)으로 기록해야 한다. 즉 규정은 스스로의 불확실성을 기록 방향으로 해소하는 것 이며 — Part 1904 전체에서 단 하나의 기록 기본(defaults-to-record) 규칙이다.

  6. osha_evaluate_hearing_loss (1904.10) — Part 1904을 들의 기록 기준 가운데 온전히 산술에만 의하는 것 하나이자, 이 서버의 tool 중에 조회가 아닌 계산을 수행하는 유일한 도구. 같은 귀 양쪽에서 두 가지 검사가 모두 나와야 한다: 기준쪽에 비례한 표준 역치변화(기준 임계치 변위)의 측정치 10 dB, 그리고 청음 0기준 기준 25 dB 이상의 총 청력값 레벨 — 각각 2000, 3000, 4000 Hz를 평균한 값. 한 귀에 STS이고, 다른 쪽 귀에 25dB level . 또한 것은 기록되지 않는다. The noise age 보정은 shift 검사에만 적용되며, 25dB test 는 조정치 않는다.

  7. osha_assess_recordability (1904.4) — 기록 대상인가? (앞서 맨 밑에 있는 앵커로서)

  8. osha_check_severe_injury_reporting (1904.39) — OSHA에 보고해야 하는 결과가? 그리고 이 때까지 클꼭 요? 사망(8시간), 입원·절단·안과 상실(24시간) 각각에 대한 실제 마감시각의 timestamp을 반환한다 — 마감 계산 재료는 당사자가 통보 알게 된 시점부터 계산한다. 사고의 임계 시간을 확인하여 이미 마감이 지났는지를 flag 구분합니다.

  9. osha_classify_300_log_entry (1904.29) — 결과가 다양할 때 최상위 심각 결과 원칙에 따라 300 로그의 어떤 결과 컬럼(G/H/I/J)에 지정할지, 상해/질으로 유형 컬럼, 및 180일로 상한을 두는 근부재 말일수를 분류한다.

  10. osha_check_privacy_case (1904.29(b)(6)-(9)) — 직원의 姓名이 로그에 정말 진짜 표시되어도 가능한 것인 것? 이들도 다시 폐쇄 목록이고, 양방향으로만 폐쇄되어 있다: (b)(7)은 여섯 가지 프라이버시 우려 사례를 열거한 반면 (b)(8)은 그 밖의 모든 것을 프라이버시 케이스로 취급하는 것을 금지하고 있다 — 고용주는 동정으로 그 목록을 넓힐 수도, 무시할 수도 없도록 만든다. 반환하는 것은 로그에 쓰인 실제 텍스트(리터럴 privacy case)에 추가해, 그 뒤에 따르는 하나씩 의무를 반환한다: (b)(6)의 별도 지정 기밀 리스트, 사건 기술만으로도 해당 근로자를 알게 되는 가능 있을 때 그 기재를 재량대로 작성하는 권한((b)(9)), 그리고 기록을 정부기관 대표 이외의 사람에게 교부하는 경우 식별 정보 일부(redaction)(b)(10)).

  11. osha_route_to_establishment_log (1904.30) — 어느 사업장의 300번 로그에 올릴 것인가, 이 한 명의 부상사고에 대한 최종 질문이다. The rule is contrary to intuition: 여기서 사건은 사람이 아니라 장소를 따른다. 회사 다른 사업장에 가서 교대 근무하다 다친 사람은 그 사업장의 로그에 기록된다 — 그것은 그 사업장의 TRIR를 커짐에 따라 움직이는 수치가 된다. 모든 사밀에서 벗어난 장비서의 부상 — 고객 현장, 운송 중, 원격 근무 — 은 근로자가 평상시 정규 근무를 사업장의 로그에 살린다.

범위: Part 1904, 그 외는 없다

이 곳을 그 대답은 하나에 하나의 질문을 하고 있다 — 누가 다가 부상입니까; OSHA는 나에게 그것을 기록하하고 보고하(Report)라고 무엇을 요구하는가? 그러한 것 이래가 29 CFR part 내내 1904 규정을 통뻐가며, 위 10가지 도구들은 그 규정을 강제하는 결정들을 파악하기 위한 것이다.

배포 는 하나는 설명서

작업을 두 가지 단위표로 두는데, 서로 다른 질문을 답하기 때문입니다. ** 서버는 "판정"을 하고, Skill은 언제 그 도구에게 물을지 알고 있습니다.

지는 안내할 사건: 서버란 상식 — 세 개의 진입점, 하나의 1엔진

진입점

전송 transport

사용

dist/index.js

stdio

Claude Desktop, 로컬 개발 환경 of local dev

dist/http.js

Streamable HTTP

컨테이너를 사용한 컨테이너 노드 즉 Node 호스트

src/worker.ts

Streamable HTTP

Cloudflare Workers

세 엔트리 포인트가 모두 같은 createServer() engine을쓰며, 같은 11 종류의 도구와 15 세트 of datasets이- src/tools/는 쓸 어느것이 통탈되는 것 상관하지 못합니다. 그 이식성리는 포트의 이식 작업이 아닌, 초기 진행에서 따라온 두 가지에서 왔습니다: 판정은 순수 함수이며 datasets.ts가 JSON와의 단일 접점이다.

모든 변형은 stateless 한 — 요청별로 fresh 서버가, 세션 ID가 없고, 호출 사이에 아무것도 변수 것이 없는데, 그 이유에 모든 tool이 번들 된 데이터에 대한 순수 조회(pure lobby)보다 이다. /health는 각 data set의 나이를 aging 스럽새드(decay threshold)에 대조 검사하여 하나라도 stale 지면 503을 반환합니다 — 그래서 호스팅 배포 환경에도 빌드가 적용되는 동일 규칙으로 감시된다.

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:workerworkerd 이용, 도구를로 실제 실행하는 유일한 scenario check. 다른 두 smoke test는 Node에서 실행되는데, 스페어 본질족으로 처리 코드 안에 Node 기본 내장(built-ins)이 들어오는 것을 볼핵 수 없다 — 배포 의 실패가 가장 정확하게 초표면에 드러나는 바로 그 지점을 놓친다. nodejs_compatwrangler.toml에서 의도적으로 OFF로 되어 있어서, 개발 중 결장이 조용히 삼아가술 수 없고 цели 명확하게 실패로 나타나게 한다.

worker는 POST만 허용. stateless 서버가 초기 message을 막 신지 시작하지 않다 때문에, GET SSE 스트림에 보낼 신호 척도 없아져서, 그 커넥션은 계속닳아 열리게 된다; workerd의는 요청의 응답이 완결되지 않으면 그 요청을 취소. 405와 함께 Allow: POST는 "서버→클라이언트로의 스트림은 존재하지" 않음을 프로토콜이 말하는 방식이다.

의도적으로 인증이 없다. 서버는 공포 규정 텍스트(publicly published regulatory text)를 반환 하고 상태면 저장하지 인증 것이 없다며? 접근 제어는 그서(서버 앞)이라 — Cloudflare Access 또는 OAuth 레벨 — 내부 반쪽 구현 보다 앞단의 걱정거리다.

속도 레이트 리 미팅

Rate 미팅(레잇 그 인식)은 단 하나의 exception이며, 그것 데ployment 있고 주변 아 중간, worker 장치 내부에 있다. 이 배포는 workers.dev에 있으며 하는 것은 계정의 존(zone)이 아니, 따라서 WAF rate — 하는 규칙에는 생붙일 대상 중이어다? 이 값은 wrangler.toml에서 [[ratelimits]] 바인딩으로 declared 하고, 이는 또한 이 매거드를 또 describe -- 만들 행하고 버전 관리며, 아무도 diff를 안 대시보드에 있어 돌인 것 없기도 조직 배포와ravel — 함을 의미하기.

같은 클라이언트 IPv4마다 분위 300 요청이로 된다. 분명 넉넉하게 준다: 즉 이기준 리밋은 rate이 IP로 물이고, 하나의 회사 NAT 뒤에 여러 안전 전문인 보가 단 한 rate key을 공유하게 된다. 자살 관리들장 통화 시 하나당 15 요청 그럼 여러ما 사람이 동시 일하면 100/min 초파한 것 행위 받을 만한 하다. 이 크기 결정은 슁륭 that model이 오류를 루프하면 그 것을 차단하도록 — 호스팅 된 배포에 위협하지 않는 그런 체인새 아니라 평범 use를 범용으로 계량하하기 위함. Limit를 넘어 가면 429 당과 Retry-After 헤더 반환.

/health은 확인 행위보다 위 단계 있다. 그래서 스케줄 폴링 한다운을 화면하는 모니터가 제한 환자를 리소가 물게 되어 소비 지출을 시킬 수 없. 이 제약은 글로발리 동시 조정된 수치 컷오프 이수는 것이 아니라 데이터 센터별 단독 시행이므로, 정확한 누적 쿼터 아닌 "자름" 형식적으로만 기능한다.

도구가 무엇을 입력으로 받는가

서버는 네트워크에서 검색 헐일을 하지 는 않고 저장하지도 않는다. 하지만 접속 입력으로는 바깥에서 들어 오고 그것들에 실제 사고를 기술하며. 그렇게 때문에 "유저 데이터 없음" is 소비자 a를 보인 없으나 것은 전송 중"이라는 것과 잊어냐릴 하는 주장입니다가 됩니다. 그 구분은 명확히 하고전짜 선언해 둘 필요가 있다. 사각세대 EHS 팀이 평가해야 할 것은 바로 그 차이 때문에서.

어떤 입력도 식별자가 아니다. 스키마 어느곳에도 이름, 사번, 생년월일, 주소, 즉 자유 텍스트에 서술 필드는 없다 — 입력의 모든 것은 사건의 속성들이고, work_related, days_away` 이며, 문서 판정이 그 외 필요한 것이 없다. 이것들은 정책이 아닌 스키마 자체의 설계 고유성: 이름을 넣을 필드 자체가 없다. Skill)의 모델을 지시하여 상대방인 데이터도 호출 경계에서 들여오지 않도록 한다 — 두쪽 모두에서 제약이 지켜진다. → Pass facts, never identities에 대한 것은 인수다.

이렇지만 일부 속성 자체가 민감성입니다. like osha_check_privacy_case는 상게 "사례만" 1904.29(b)(7)에 목록된 분류개만 입력으로 취하고 — sexual_assault, mental_illness, hiv_hepatitis_or_tuberculosis, contaminated_needlestick_or_sharps. 규정치운 것 것만 따로 특정한 까닭은 근로자가 지 못하는 로그에 올려서는 안 될 것들이 바로 그것 존재하기 때문입니다. 그리고 "결과만 있어도 // 무명임을 동일의 동일하지 않다 커녕 데이터 소수의 9 사람 사업장에서는 &: 하나의 사고 속성과 사고 날짜 있으면 동료근로자 누구에게는 dedao사람을 특정할 수 있기 때문입니다.

그 결과는 그 transport에 의해서만, 하나라그 move depends:

접근 포인트

전달되어 가는 곳

stdio

(서버를 실행하는) 그 기기 오래 유지 -- 그 항목은 여전히 AI 호스트 화면에 노출됨.

node HTTP / worker

네트워크를 경유하여 그 배포를 운영하는 미지 인측으로 передают된다. 出

어느 쪽이든 아무것도 기록되지 않습니다. 요청 로깅도, 도구 호출 로깅도, 성공 여부와 관계없이 없습니다. 이는 의도적입니다. 이러한 인자들의 로그는 그 자체로 규제 대상 저장소가 되며, 규제할 것이 없는 서버에 불필요한 부담을 줍니다. 그리고 판정은 모든 응답에 포함된 last_verified 데이터셋 버전과 입력값만으로 이미 재현 가능합니다. 응답의 출처(provenance) 정보가 감사 로그가 하는 역할을 보존 정책 없이 수행합니다.

따라서: GDPR 또는 HIPAA 하에서 실제 사례를 처리한다면 stdio로 실행하거나, 자체 호스팅 워커를 통제 가능한 인프라에서 실행하십시오. 규제 대상 사고 데이터를 타인이 호스팅하는 이 서버의 복사본으로 보내는 것은, 계약 관계가 없는 제3자에게 상해 속성을 전송하는 것을 의미합니다. 판정은 번들된 JSON에 대한 순수 함수입니다. 자체 호스팅은 wrangler deploy 한 번이면 되고 답변에는 아무 변화가 없습니다.

호스트 및 출처 검증

인증은 누가 요청할 수 있는지에 관한 것입니다. 호스트 검증은 브라우저가 타인을 대신하여 요청하도록 강제되는 상황에 관한 것이며, 어떤 업스트림 게이트웨이도 이를 소급 적용할 수 없습니다. 따라서 이 부분은 src/httpGuard.ts에서 처리되며 두 HTTP 진입점 모두에 적용됩니다.

이것이 차단하는 공격은 DNS 리바인딩입니다. 공격자 도메인이 127.0.0.1로 재해석되고, 브라우저는 요청을 동일 출처로 간주하여 사전 점검 없이 전송하며, 로컬에서 실행되는 MCP 서버가 응답합니다. Host 헤더가 여전히 이를 드러내는 요소입니다. 공격자의 도메인을 담고 있기 때문입니다. 따라서 정확히 일치하는 호스트 허용 목록이 효과적인 검사입니다.

변수

Node (dist/http.js)

Worker

HOST

바인드 주소, 기본값 0.0.0.0

MCP_ALLOWED_HOSTS

기본값 localhost:$PORT, 127.0.0.1:$PORT, [::1]:$PORT

미설정 = 무제한

MCP_ALLOWED_ORIGINS

미설정 = 무제한

미설정 = 무제한

둘 다 쉼표로 구분된 목록을 허용하며, *는 앞단의 게이트웨이가 결정을 소유할 때 검사를 끕니다. Origin은 헤더가 존재할 때만 검사됩니다. 브라우저가 아닌 MCP 클라이언트는 이를 보내지 않기 때문입니다. /health는 허용 목록 밖에 있습니다. 가동 시간 모니터는 위협 모델이 아닙니다.

노드 진입점은 기본적으로 루프백 전용입니다. 컨테이너 또는 리버스 프록시 배포는 다른 이름으로 접근되므로 MCP_ALLOWED_HOSTS를 설정해야 합니다. 설정하지 않으면 본 헤더를 명시하는 403으로 실패하며, 이는 5초면 해결되는 문제입니다. 반대의 기본값은 아무도 알아차리지 못하는 허점입니다. 바인드 주소는 보호 수단이 아닙니다. 0.0.0.0 바인딩이 기본값으로 유지되어 컨테이너가 작동하며, 허용 목록이 이를 안전하게 만듭니다.

거부된 요청은 JSON-RPC -32000 오류와 함께 403을 받습니다. 초과 크기 본문(>1 MB)은 413, 잘못된 형식의 JSON은 400을 받습니다. 클라이언트 실수는 사고로 기록되지 않습니다.

스킬

skills/osha-incident-triage/절차를 담고 있습니다. 체인이 언제 적용되는지, 호출 전에 무엇을 확립해야 하는지, 판정을 어떻게 제시하는지, 그리고 도구가 결정할 수 없는 것이 무엇인지입니다. 사고 분류를 위한 프로세스 지침을 포함하며 규제 로직을 직접 담고 있지는 않습니다.

구조

판정 로직은 순수하고 테스트 가능합니다. 서버는 그 주변의 배선입니다.

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

도구를 추가한다는 것은 src/tools/에 파일 하나(규칙), src/registrations/tools/에 파일 하나(설명 및 요약 방식), 그리고 배럴 파일에 한 줄을 추가하는 것을 의미합니다. register 접두사는 편집기 탭 바에서 해당 파일 이름을 src/tools/의 대응 파일과 구분되게 합니다.

유지할 가치가 있는 두 가지 불변 조건: 출처 정보는 ruleRecord()에 의해서만 조립되며, Resources는 도구가 로드하는 것과 동일한 DATASETS 테이블에서 생성됩니다. 따라서 어떤 도구도 읽지 않는 경로로 데이터셋이 게시될 수 없습니다.

지속적 통합

.github/workflows/ci.yml은 Node 20과 22에서 타입 검사, 빌드, 단위 테스트, 스모크 스위트를 실행합니다.

부패 검사와 npm audit은 모두 나머지 CI와 동일한 트리거에서 실행됩니다. push, pull request, 주간 일정입니다. 각각 별도의 작업으로 유지되어 어느 쪽 실패든 여러 개의 빨간 X 중 하나가 아니라 그 자체로 식별 가능합니다. npm audit은 프로덕션 취약점 권고가 있으면 빌드를 차단합니다. 개발 의존성 권고는 보고만 되고 차단하지 않습니다. 주간 일정은 이미 main에 있는 의존성 버전에 대해 게시된 권고를 잡아내는 역할을 합니다. 그 경우 재검사를 촉발할 push가 없기 때문입니다.

tsconfig.jsontest/를 제외하므로 tsc --noEmitsrc/만 검사하고 ts-jest는 npm test 중에 테스트 파일을 타입 검사합니다.

변경 관리 및 버전 관리

CHANGELOG.md는 두 개의 독립적인 릴리스 차원에 걸쳐 모든 변경 사항을 추적합니다.

  • 코드: 판정 로직, 도구 스키마, 서버 전송은 시맨틱 버전 관리를 따릅니다.

  • 규제 데이터: src/data/ 아래에 번들된 eCFR JSON 데이터셋. 현재 eCFR 텍스트에 대해 데이터셋을 재검증하면 last_verified 날짜가 갱신되고 규제 텍스트가 변경되지 않았더라도 패치 업데이트로 릴리스되어 규정 준수 팀을 위한 감사 가능한 출처를 유지합니다.

  • 강제 부패 방지: CI는 scripts/check-decay.ts를 주간으로 실행하여 수동 재검증 없이 데이터셋이 365일 부패 임계값을 초과하면 빌드를 실패시킵니다.

  • 릴리스: GitHub의 버전 태그(vX.Y.Z)는 .github/workflows/release.yml을 트리거하여 전체 검증 스위트(타입 검사, 테스트, 스모크, 부패, 감사)를 실행하고 검증된 GitHub 릴리스를 생성합니다.

개발

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

npx @modelcontextprotocol/inspector로 로컬 연결하거나, dist/index.js를 가리키는 claude_desktop_config.json에 추가하십시오.

npm run smoke:workernpm run dev:worker는 Node 22 이상이 필요합니다. wrangler가 그렇게 요구하기 때문입니다. 다른 모든 것은 Node 20에서 실행되며, engines는 의도적으로 >=20으로 유지됩니다. 해당 필드는 서버를 설치하고 실행할 수 있는 사람에 대한 주장이며, 서버에는 SDK와 zod만 필요합니다. Wrangler는 개발 도구일 뿐 소비자에게 전달되지 않으므로 그 요구 사항이 패키지의 요구 사항은 아닙니다. CI는 정확히 그 이유로 매트릭스에 Node 20을 유지하며 거기서 워커 스모크만 건너뜁니다.

평가

evals/recordkeeping-evals.xml — LLM이 도구를 통해 올바른 답에 도달하는지 테스트하는 47개의 질문으로, 단위 테스트로는 다룰 수 없는 부분입니다. 모든 답변은 실제 MCP 클라이언트로 빌드된 서버를 구동하여 생성되었으며, 추적 기록은 evals/README.md에 있습니다. 47개 중 대부분은 메모리에서 추론하는 모델이 직관적으로 틀리기 쉬운 답을 가지고 있습니다.

고지 사항

참고 및 분류 전용입니다. 법률 자문이 아니며 의학적 판정도 아닙니다. 기록 가능성 경계 사례는 종종 PLHCP 또는 법률 자문이 필요합니다. 업무 관련성(1904.5)은 결정적 경로를 따라서만 판정됩니다. 불명확한 발생 원인, 출장 상태, 재택 근무, 그리고 확립되지 않은 "단독" 판정은 판정 대신 requires_judgment를 반환합니다.

Install Server
A
license - permissive license
A
quality
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    A deterministic MCP server for legal intake triage that provides practice-area lookup, conflict screening, matter validation, follow-up drafting, and triage logging with a hard conflicts gate.
    Apache 2.0
  • A
    license
    A
    quality
    A
    maintenance
    First-line incident triage you can trust: ranked root-cause hypotheses where every claim cites a real evidence handle — and the agent abstains rather than guess.
    1
    1
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    MCP server for US workplace-safety standards (OSHA 29 CFR parts 1900–1990). Enables querying safety regulations via natural language through the Pipeworx gateway.
    14
    MIT

View all related MCP servers

Related MCP Connectors

  • Diagnoses, drugs & lab codes: ICD-11, SNOMED, LOINC, RxNorm, MeSH, ATC, CID-10. 37 tools, MIT.

  • FDA medical-device regulatory intelligence from keyless openFDA datasets.

  • Read-only tools over the Psychopathia Machinalis nosology: 79 conditions, 11 tools.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/srhtdmrkl/osha-recordkeeping-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server