@ansvar/ch-farm-safety-mcp 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/check-freshness.yml +53 -0
- package/.github/workflows/ci.yml +21 -0
- package/.github/workflows/codeql.yml +30 -0
- package/.github/workflows/ghcr-build.yml +45 -0
- package/.github/workflows/gitleaks.yml +24 -0
- package/.github/workflows/ingest.yml +67 -0
- package/.github/workflows/publish.yml +24 -0
- package/CHANGELOG.md +23 -0
- package/CODEOWNERS +1 -0
- package/COVERAGE.md +54 -0
- package/DISCLAIMER.md +51 -0
- package/Dockerfile +26 -0
- package/LICENSE +17 -0
- package/PRIVACY.md +25 -0
- package/README.md +129 -0
- package/SECURITY.md +25 -0
- package/TOOLS.md +140 -0
- package/data/coverage.json +22 -0
- package/data/database.db +0 -0
- package/data/sources.yml +36 -0
- package/dist/db.d.ts +25 -0
- package/dist/db.d.ts.map +1 -0
- package/dist/db.js +200 -0
- package/dist/db.js.map +1 -0
- package/dist/http-server.d.ts +2 -0
- package/dist/http-server.d.ts.map +1 -0
- package/dist/http-server.js +250 -0
- package/dist/http-server.js.map +1 -0
- package/dist/jurisdiction.d.ts +18 -0
- package/dist/jurisdiction.d.ts.map +1 -0
- package/dist/jurisdiction.js +16 -0
- package/dist/jurisdiction.js.map +1 -0
- package/dist/metadata.d.ts +10 -0
- package/dist/metadata.d.ts.map +1 -0
- package/dist/metadata.js +20 -0
- package/dist/metadata.js.map +1 -0
- package/dist/server.d.ts +3 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +196 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/about.d.ts +15 -0
- package/dist/tools/about.d.ts.map +1 -0
- package/dist/tools/about.js +27 -0
- package/dist/tools/about.js.map +1 -0
- package/dist/tools/check-freshness.d.ts +15 -0
- package/dist/tools/check-freshness.d.ts.map +1 -0
- package/dist/tools/check-freshness.js +26 -0
- package/dist/tools/check-freshness.js.map +1 -0
- package/dist/tools/get-accident-reporting.d.ts +49 -0
- package/dist/tools/get-accident-reporting.d.ts.map +1 -0
- package/dist/tools/get-accident-reporting.js +31 -0
- package/dist/tools/get-accident-reporting.js.map +1 -0
- package/dist/tools/get-chemical-safety.d.ts +47 -0
- package/dist/tools/get-chemical-safety.d.ts.map +1 -0
- package/dist/tools/get-chemical-safety.js +31 -0
- package/dist/tools/get-chemical-safety.js.map +1 -0
- package/dist/tools/get-machinery-safety.d.ts +46 -0
- package/dist/tools/get-machinery-safety.d.ts.map +1 -0
- package/dist/tools/get-machinery-safety.js +31 -0
- package/dist/tools/get-machinery-safety.js.map +1 -0
- package/dist/tools/get-risk-assessment-requirements.d.ts +47 -0
- package/dist/tools/get-risk-assessment-requirements.d.ts.map +1 -0
- package/dist/tools/get-risk-assessment-requirements.js +31 -0
- package/dist/tools/get-risk-assessment-requirements.js.map +1 -0
- package/dist/tools/get-young-worker-rules.d.ts +47 -0
- package/dist/tools/get-young-worker-rules.d.ts.map +1 -0
- package/dist/tools/get-young-worker-rules.js +31 -0
- package/dist/tools/get-young-worker-rules.js.map +1 -0
- package/dist/tools/list-sources.d.ts +18 -0
- package/dist/tools/list-sources.d.ts.map +1 -0
- package/dist/tools/list-sources.js +51 -0
- package/dist/tools/list-sources.js.map +1 -0
- package/dist/tools/search-bul-guidance.d.ts +23 -0
- package/dist/tools/search-bul-guidance.d.ts.map +1 -0
- package/dist/tools/search-bul-guidance.js +35 -0
- package/dist/tools/search-bul-guidance.js.map +1 -0
- package/dist/tools/search-safety-rules.d.ts +25 -0
- package/dist/tools/search-safety-rules.d.ts.map +1 -0
- package/dist/tools/search-safety-rules.js +26 -0
- package/dist/tools/search-safety-rules.js.map +1 -0
- package/docker-compose.yml +12 -0
- package/eslint.config.js +27 -0
- package/package.json +54 -0
- package/scripts/ingest.ts +879 -0
- package/server.json +31 -0
- package/src/db.ts +241 -0
- package/src/http-server.ts +282 -0
- package/src/jurisdiction.ts +30 -0
- package/src/metadata.ts +30 -0
- package/src/server.ts +219 -0
- package/src/tools/about.ts +28 -0
- package/src/tools/check-freshness.ts +42 -0
- package/src/tools/get-accident-reporting.ts +52 -0
- package/src/tools/get-chemical-safety.ts +52 -0
- package/src/tools/get-machinery-safety.ts +52 -0
- package/src/tools/get-risk-assessment-requirements.ts +52 -0
- package/src/tools/get-young-worker-rules.ts +52 -0
- package/src/tools/list-sources.ts +65 -0
- package/src/tools/search-bul-guidance.ts +51 -0
- package/src/tools/search-safety-rules.ts +35 -0
- package/tests/db.test.ts +121 -0
- package/tests/helpers/seed-db.ts +134 -0
- package/tests/jurisdiction.test.ts +54 -0
- package/tests/tools/about.test.ts +44 -0
- package/tests/tools/check-freshness.test.ts +68 -0
- package/tests/tools/list-sources.test.ts +75 -0
- package/tests/tools/search-safety-rules.test.ts +75 -0
- package/tsconfig.json +19 -0
- package/vitest.config.ts +9 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
name: Check Data Freshness
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
schedule:
|
|
5
|
+
- cron: "0 6 * * 1"
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
issues: write
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
freshness:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- uses: actions/setup-node@v4
|
|
18
|
+
with:
|
|
19
|
+
node-version: "20"
|
|
20
|
+
cache: npm
|
|
21
|
+
- run: npm ci
|
|
22
|
+
|
|
23
|
+
- name: Check freshness
|
|
24
|
+
id: check
|
|
25
|
+
run: |
|
|
26
|
+
OUTPUT=$(npm run freshness:check --silent 2>&1 || true)
|
|
27
|
+
echo "$OUTPUT"
|
|
28
|
+
if echo "$OUTPUT" | grep -q '"status":"stale"'; then
|
|
29
|
+
echo "stale=true" >> "$GITHUB_OUTPUT"
|
|
30
|
+
else
|
|
31
|
+
echo "stale=false" >> "$GITHUB_OUTPUT"
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
- name: Open issue if stale
|
|
35
|
+
if: steps.check.outputs.stale == 'true'
|
|
36
|
+
uses: actions/github-script@v7
|
|
37
|
+
with:
|
|
38
|
+
script: |
|
|
39
|
+
const existing = await github.rest.issues.listForRepo({
|
|
40
|
+
owner: context.repo.owner,
|
|
41
|
+
repo: context.repo.repo,
|
|
42
|
+
labels: 'data-freshness',
|
|
43
|
+
state: 'open',
|
|
44
|
+
});
|
|
45
|
+
if (existing.data.length === 0) {
|
|
46
|
+
await github.rest.issues.create({
|
|
47
|
+
owner: context.repo.owner,
|
|
48
|
+
repo: context.repo.repo,
|
|
49
|
+
title: 'Data is stale — re-ingestion needed',
|
|
50
|
+
body: 'The `check_data_freshness` tool reports data is older than 90 days.\n\nRun `gh workflow run ingest.yml` or `npm run ingest:full` to refresh.',
|
|
51
|
+
labels: ['data-freshness'],
|
|
52
|
+
});
|
|
53
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, dev]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
build:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
- uses: actions/setup-node@v4
|
|
15
|
+
with:
|
|
16
|
+
node-version: "20"
|
|
17
|
+
cache: npm
|
|
18
|
+
- run: npm ci
|
|
19
|
+
- run: npm run typecheck
|
|
20
|
+
- run: npm run lint
|
|
21
|
+
- run: npm test
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
name: CodeQL
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, dev]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
schedule:
|
|
9
|
+
- cron: "30 4 * * 1"
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
actions: read
|
|
13
|
+
contents: read
|
|
14
|
+
security-events: write
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
analyze:
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
strategy:
|
|
20
|
+
matrix:
|
|
21
|
+
language: [javascript-typescript]
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v4
|
|
24
|
+
- uses: github/codeql-action/init@v3
|
|
25
|
+
with:
|
|
26
|
+
languages: ${{ matrix.language }}
|
|
27
|
+
- uses: github/codeql-action/autobuild@v3
|
|
28
|
+
- uses: github/codeql-action/analyze@v3
|
|
29
|
+
with:
|
|
30
|
+
category: "/language:${{ matrix.language }}"
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
name: Build and Push to GHCR
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
concurrency:
|
|
9
|
+
group: build-${{ github.ref }}
|
|
10
|
+
cancel-in-progress: true
|
|
11
|
+
|
|
12
|
+
env:
|
|
13
|
+
REGISTRY: ghcr.io
|
|
14
|
+
IMAGE_NAME: ch-farm-safety-mcp
|
|
15
|
+
|
|
16
|
+
permissions:
|
|
17
|
+
contents: read
|
|
18
|
+
packages: write
|
|
19
|
+
|
|
20
|
+
jobs:
|
|
21
|
+
build-and-push:
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
steps:
|
|
24
|
+
- uses: actions/checkout@v4
|
|
25
|
+
- uses: docker/setup-buildx-action@v3
|
|
26
|
+
- uses: docker/login-action@v3
|
|
27
|
+
with:
|
|
28
|
+
registry: ghcr.io
|
|
29
|
+
username: ${{ github.actor }}
|
|
30
|
+
password: ${{ secrets.GITHUB_TOKEN }}
|
|
31
|
+
- uses: docker/metadata-action@v5
|
|
32
|
+
id: meta
|
|
33
|
+
with:
|
|
34
|
+
images: ${{ env.REGISTRY }}/ansvar-systems/${{ env.IMAGE_NAME }}
|
|
35
|
+
tags: |
|
|
36
|
+
type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'main') }}
|
|
37
|
+
type=sha,prefix=sha-,format=short
|
|
38
|
+
- uses: docker/build-push-action@v5
|
|
39
|
+
with:
|
|
40
|
+
context: .
|
|
41
|
+
push: true
|
|
42
|
+
tags: ${{ steps.meta.outputs.tags }}
|
|
43
|
+
platforms: linux/amd64
|
|
44
|
+
cache-from: type=gha
|
|
45
|
+
cache-to: type=gha,mode=max
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
name: Gitleaks
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, dev]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
scan:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
with:
|
|
18
|
+
fetch-depth: 0
|
|
19
|
+
- name: Install gitleaks
|
|
20
|
+
run: |
|
|
21
|
+
curl -sSfL https://github.com/gitleaks/gitleaks/releases/download/v8.18.4/gitleaks_8.18.4_linux_x64.tar.gz | tar xz
|
|
22
|
+
sudo mv gitleaks /usr/local/bin/
|
|
23
|
+
- name: Run gitleaks
|
|
24
|
+
run: gitleaks detect --source . --verbose
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
name: Ingest Data
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
inputs:
|
|
6
|
+
mode:
|
|
7
|
+
description: "Ingestion mode"
|
|
8
|
+
required: true
|
|
9
|
+
default: "incremental"
|
|
10
|
+
type: choice
|
|
11
|
+
options:
|
|
12
|
+
- incremental
|
|
13
|
+
- full
|
|
14
|
+
- diff-only
|
|
15
|
+
schedule:
|
|
16
|
+
- cron: "0 3 1 * *"
|
|
17
|
+
|
|
18
|
+
permissions:
|
|
19
|
+
contents: write
|
|
20
|
+
pull-requests: write
|
|
21
|
+
|
|
22
|
+
jobs:
|
|
23
|
+
ingest:
|
|
24
|
+
runs-on: ubuntu-latest
|
|
25
|
+
steps:
|
|
26
|
+
- uses: actions/checkout@v4
|
|
27
|
+
- uses: actions/setup-node@v4
|
|
28
|
+
with:
|
|
29
|
+
node-version: "20"
|
|
30
|
+
cache: npm
|
|
31
|
+
- run: npm ci
|
|
32
|
+
|
|
33
|
+
- name: Run ingestion
|
|
34
|
+
run: |
|
|
35
|
+
case "${{ inputs.mode || 'incremental' }}" in
|
|
36
|
+
full) npm run ingest:full ;;
|
|
37
|
+
diff-only) npm run ingest:diff ;;
|
|
38
|
+
*) npm run ingest ;;
|
|
39
|
+
esac
|
|
40
|
+
|
|
41
|
+
- name: Update coverage.json
|
|
42
|
+
run: npm run coverage:update
|
|
43
|
+
|
|
44
|
+
- name: Check for changes
|
|
45
|
+
id: changes
|
|
46
|
+
run: |
|
|
47
|
+
if git diff --quiet data/; then
|
|
48
|
+
echo "changed=false" >> "$GITHUB_OUTPUT"
|
|
49
|
+
else
|
|
50
|
+
echo "changed=true" >> "$GITHUB_OUTPUT"
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
- name: Create PR
|
|
54
|
+
if: steps.changes.outputs.changed == 'true'
|
|
55
|
+
uses: peter-evans/create-pull-request@v6
|
|
56
|
+
with:
|
|
57
|
+
branch: auto/ingest-update
|
|
58
|
+
title: "data: update Swiss farm safety data"
|
|
59
|
+
body: |
|
|
60
|
+
Automated data ingestion run.
|
|
61
|
+
|
|
62
|
+
Mode: `${{ inputs.mode || 'incremental' }}`
|
|
63
|
+
Date: `${{ github.event.repository.updated_at }}`
|
|
64
|
+
|
|
65
|
+
Review the data changes in `data/` before merging.
|
|
66
|
+
commit-message: "data: update Swiss farm safety data"
|
|
67
|
+
delete-branch: true
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
name: Publish to npm
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
9
|
+
id-token: write
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
publish:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
- uses: actions/setup-node@v4
|
|
17
|
+
with:
|
|
18
|
+
node-version: "20"
|
|
19
|
+
registry-url: "https://registry.npmjs.org"
|
|
20
|
+
- run: npm ci
|
|
21
|
+
- run: npm run build
|
|
22
|
+
- run: npm publish --provenance --access public
|
|
23
|
+
env:
|
|
24
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
Format based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
6
|
+
|
|
7
|
+
## [0.1.0] - 2026-04-05
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Initial release with 10 tools for Swiss farm workplace safety
|
|
12
|
+
- `search_safety_rules` with tiered FTS5 search (phrase, AND, prefix, stemmed, OR, LIKE fallback)
|
|
13
|
+
- `get_risk_assessment_requirements` for EKAS/VUV obligations by activity type
|
|
14
|
+
- `get_machinery_safety` for ROPS, Gurtpflicht, MFK, PTO requirements
|
|
15
|
+
- `get_chemical_safety` for MAK exposure limits, PPE, storage rules
|
|
16
|
+
- `get_young_worker_rules` for Jugendarbeitsschutz restrictions (ArGV 5)
|
|
17
|
+
- `get_accident_reporting` for deadlines, forms, insurer by severity
|
|
18
|
+
- `search_bul_guidance` for BUL/SPAA documents and campaigns
|
|
19
|
+
- `about`, `list_sources`, `check_data_freshness` metadata tools
|
|
20
|
+
- Streamable HTTP transport for remote access
|
|
21
|
+
- Docker image with non-root user and health check
|
|
22
|
+
- CI/CD: GHCR build, npm publish, CodeQL, Gitleaks, freshness check
|
|
23
|
+
- Data from BUL/SPAA, Suva, EKAS, Agriss, SECO
|
package/CODEOWNERS
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
* @ansvar-systems/mcp-team
|
package/COVERAGE.md
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Coverage — ch-farm-safety-mcp
|
|
2
|
+
|
|
3
|
+
## Jurisdiction
|
|
4
|
+
|
|
5
|
+
Switzerland (CH)
|
|
6
|
+
|
|
7
|
+
## Data Summary
|
|
8
|
+
|
|
9
|
+
| Table | Records | Description |
|
|
10
|
+
|-------|---------|-------------|
|
|
11
|
+
| safety_rules | 30 | BUL lebenswichtige Regeln, Suva requirements, EKAS guidelines |
|
|
12
|
+
| risk_assessments | 7 | Risk assessment obligations per activity type (VUV/EKAS) |
|
|
13
|
+
| machinery_safety | 10 | ROPS, Gurtpflicht, MFK, PTO guards by machine type |
|
|
14
|
+
| chemical_safety | 7 | MAK exposure limits, PPE, storage rules by substance |
|
|
15
|
+
| young_worker_rules | 5 | Jugendarbeitsschutz restrictions by age group (ArGV 5) |
|
|
16
|
+
| accident_reporting | 5 | Reporting deadlines, forms, insurer by severity |
|
|
17
|
+
| bul_guidance | 15 | BUL/SPAA guidance documents, fact sheets, campaigns |
|
|
18
|
+
| **Total** | **79** | |
|
|
19
|
+
|
|
20
|
+
## Safety Areas (search_safety_rules topics)
|
|
21
|
+
|
|
22
|
+
- `maschinen` -- agricultural machinery (Traktor, Maehdrescher, Motorsaege)
|
|
23
|
+
- `tiere` -- livestock handling (Rinder, Pferde, Schweine)
|
|
24
|
+
- `wald` -- forestry work (Holzerei, Baumfaellen)
|
|
25
|
+
- `hoehe` -- working at height (Silo, Dach, Leiter)
|
|
26
|
+
- `chemie` -- chemical exposure (PSM, Duenger)
|
|
27
|
+
- `silogas` -- silo gas hazards (CO2, NO2)
|
|
28
|
+
- `allgemein` -- general farm safety
|
|
29
|
+
|
|
30
|
+
## Legal Framework Covered
|
|
31
|
+
|
|
32
|
+
| Law/Regulation | Abbreviation | Scope |
|
|
33
|
+
|----------------|-------------|-------|
|
|
34
|
+
| Arbeitsgesetz | ArG (SR 822.11) | Working conditions, young worker protection |
|
|
35
|
+
| Verordnung ueber die Verhuetung von Unfaellen | VUV (SR 832.30) | Accident prevention obligations |
|
|
36
|
+
| Unfallversicherungsgesetz | UVG (SR 832.20) | Accident insurance, reporting obligations |
|
|
37
|
+
| Chemikalien-Risikoreduktions-Verordnung | ChemRRV (SR 814.81) | PSM application, chemical handling |
|
|
38
|
+
| Maschinenverordnung | MaschV (SR 819.14) | Machinery safety certification |
|
|
39
|
+
| Jugendarbeitsschutzverordnung | ArGV 5 (SR 822.115) | Young worker restrictions |
|
|
40
|
+
| EKAS Richtlinie 6508 | ASA | Systematic safety work, Branchenloesung |
|
|
41
|
+
|
|
42
|
+
## Data Sources
|
|
43
|
+
|
|
44
|
+
- **BUL/SPAA** -- Beratungsstelle fuer Unfallverhuetung in der Landwirtschaft (bul.ch)
|
|
45
|
+
- **Suva** -- Schweizerische Unfallversicherungsanstalt (suva.ch)
|
|
46
|
+
- **EKAS** -- Eidg. Koordinationskommission fuer Arbeitssicherheit (ekas.admin.ch)
|
|
47
|
+
- **Agriss** -- Unfallstatistik Schweizer Landwirtschaft (BUL/Agroscope)
|
|
48
|
+
- **SECO** -- Staatssekretariat fuer Wirtschaft (Jugendarbeitsschutz)
|
|
49
|
+
|
|
50
|
+
## Staleness Threshold
|
|
51
|
+
|
|
52
|
+
90 days. Check with `check_data_freshness` tool or `npm run freshness:check`.
|
|
53
|
+
|
|
54
|
+
Last ingest: 2026-04-05
|
package/DISCLAIMER.md
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Haftungsausschluss / Disclaimer
|
|
2
|
+
|
|
3
|
+
## Deutsch
|
|
4
|
+
|
|
5
|
+
Die in diesem MCP-Server bereitgestellten Daten dienen ausschliesslich der Information und ersetzen keine professionelle Sicherheitsberatung.
|
|
6
|
+
|
|
7
|
+
Die Inhalte basieren auf oeffentlich zugaenglichen Dokumenten der folgenden Stellen:
|
|
8
|
+
|
|
9
|
+
- **BUL/SPAA** -- Beratungsstelle fuer Unfallverhuetung in der Landwirtschaft
|
|
10
|
+
- **Suva** -- Schweizerische Unfallversicherungsanstalt
|
|
11
|
+
- **EKAS** -- Eidgenoessische Koordinationskommission fuer Arbeitssicherheit
|
|
12
|
+
- **Agriss** -- Unfallstatistik Schweizer Landwirtschaft (BUL / Agroscope)
|
|
13
|
+
- **SECO** -- Staatssekretariat fuer Wirtschaft (Jugendarbeitsschutz)
|
|
14
|
+
|
|
15
|
+
Die rechtlich verbindlichen Texte sind die amtlichen Publikationen in der Systematischen Rechtssammlung (SR), insbesondere:
|
|
16
|
+
|
|
17
|
+
- Arbeitsgesetz (ArG, SR 822.11)
|
|
18
|
+
- Verordnung ueber die Verhuetung von Unfaellen und Berufskrankheiten (VUV, SR 832.30)
|
|
19
|
+
- Unfallversicherungsgesetz (UVG, SR 832.20)
|
|
20
|
+
- Chemikalien-Risikoreduktions-Verordnung (ChemRRV, SR 814.81)
|
|
21
|
+
- Jugendarbeitsschutzverordnung (ArGV 5, SR 822.115)
|
|
22
|
+
|
|
23
|
+
Vor der Umsetzung von Sicherheitsmassnahmen ist stets die BUL/SPAA, die Suva oder eine qualifizierte Sicherheitsfachperson beizuziehen. Betriebsspezifische Risikobeurteilungen gemaess VUV Art. 3-10 und der EKAS Branchenloesung Landwirtschaft sind eigenstaendig durchzufuehren.
|
|
24
|
+
|
|
25
|
+
Ansvar Systems uebernimmt keine Haftung fuer die Richtigkeit, Vollstaendigkeit oder Aktualitaet der bereitgestellten Daten.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## English
|
|
30
|
+
|
|
31
|
+
The data provided by this MCP server is for informational purposes only and does not constitute professional safety advice.
|
|
32
|
+
|
|
33
|
+
Content is derived from publicly available documents published by:
|
|
34
|
+
|
|
35
|
+
- **BUL/SPAA** -- Swiss Advisory Service for Accident Prevention in Agriculture
|
|
36
|
+
- **Suva** -- Swiss National Accident Insurance Fund
|
|
37
|
+
- **EKAS** -- Federal Coordination Commission for Occupational Safety
|
|
38
|
+
- **Agriss** -- Swiss Agricultural Accident Statistics (BUL / Agroscope)
|
|
39
|
+
- **SECO** -- State Secretariat for Economic Affairs (Young Worker Protection)
|
|
40
|
+
|
|
41
|
+
The legally binding texts are the official publications in the Swiss Systematic Collection of Federal Legislation (SR), including:
|
|
42
|
+
|
|
43
|
+
- Employment Act (ArG, SR 822.11)
|
|
44
|
+
- Ordinance on the Prevention of Accidents and Occupational Diseases (VUV, SR 832.30)
|
|
45
|
+
- Accident Insurance Act (UVG, SR 832.20)
|
|
46
|
+
- Chemical Risk Reduction Ordinance (ChemRRV, SR 814.81)
|
|
47
|
+
- Young Workers Protection Ordinance (ArGV 5, SR 822.115)
|
|
48
|
+
|
|
49
|
+
Always consult BUL/SPAA, Suva, or a qualified safety professional before implementing safety measures. Farm-specific risk assessments as required by VUV Art. 3-10 and the EKAS sector solution for agriculture must be conducted independently.
|
|
50
|
+
|
|
51
|
+
Ansvar Systems accepts no liability for the accuracy, completeness, or currency of the data provided.
|
package/Dockerfile
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
FROM node:20-slim AS builder
|
|
2
|
+
RUN apt-get update && apt-get install -y python3 make g++ && rm -rf /var/lib/apt/lists/*
|
|
3
|
+
WORKDIR /app
|
|
4
|
+
COPY package*.json ./
|
|
5
|
+
RUN npm ci
|
|
6
|
+
COPY tsconfig.json ./
|
|
7
|
+
COPY src/ src/
|
|
8
|
+
RUN npm run build
|
|
9
|
+
|
|
10
|
+
FROM node:20-slim
|
|
11
|
+
RUN apt-get update && apt-get install -y python3 make g++ && rm -rf /var/lib/apt/lists/*
|
|
12
|
+
RUN addgroup --system --gid 1001 nodejs && \
|
|
13
|
+
adduser --system --uid 1001 nodejs
|
|
14
|
+
WORKDIR /app
|
|
15
|
+
COPY package*.json ./
|
|
16
|
+
RUN npm ci --omit=dev && npm cache clean --force && apt-get purge -y python3 make g++ && apt-get autoremove -y
|
|
17
|
+
COPY --from=builder /app/dist dist/
|
|
18
|
+
COPY data/ data/
|
|
19
|
+
RUN chown -R nodejs:nodejs /app/data
|
|
20
|
+
USER nodejs
|
|
21
|
+
ENV NODE_ENV=production
|
|
22
|
+
ENV PORT=3000
|
|
23
|
+
EXPOSE 3000
|
|
24
|
+
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
|
|
25
|
+
CMD node -e "require('http').get('http://localhost:' + process.env.PORT + '/health', (r) => { process.exit(r.statusCode === 200 ? 0 : 1) })"
|
|
26
|
+
CMD ["node", "dist/http-server.js"]
|
package/LICENSE
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
you may not use this file except in compliance with the License.
|
|
7
|
+
You may obtain a copy of the License at
|
|
8
|
+
|
|
9
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
|
|
11
|
+
Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
See the License for the specific language governing permissions and
|
|
15
|
+
limitations under the License.
|
|
16
|
+
|
|
17
|
+
Copyright 2026 Ansvar Systems
|
package/PRIVACY.md
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Privacy Policy
|
|
2
|
+
|
|
3
|
+
## Data Processing
|
|
4
|
+
|
|
5
|
+
This MCP server processes **no personal data**. It serves pre-ingested, publicly available Swiss farm safety information.
|
|
6
|
+
|
|
7
|
+
## What This Server Does Not Do
|
|
8
|
+
|
|
9
|
+
- Does not collect, store, or transmit user queries
|
|
10
|
+
- Does not use cookies, tracking pixels, or analytics
|
|
11
|
+
- Does not require authentication or user accounts
|
|
12
|
+
- Does not log IP addresses or request metadata beyond standard HTTP server logs
|
|
13
|
+
- Does not process any data subject to GDPR, nDSG (Swiss Data Protection Act), or any other privacy regulation
|
|
14
|
+
|
|
15
|
+
## Data Sources
|
|
16
|
+
|
|
17
|
+
All data is sourced from public-sector publications by BUL/SPAA, Suva, EKAS, Agriss, and SECO. No personal data is included in the dataset.
|
|
18
|
+
|
|
19
|
+
## Remote Endpoint
|
|
20
|
+
|
|
21
|
+
The Streamable HTTP endpoint at `mcp.ansvar.eu` is proxied through Cloudflare. Cloudflare may process connection metadata (IP, TLS fingerprint) according to their privacy policy. Ansvar Systems does not access or retain this metadata.
|
|
22
|
+
|
|
23
|
+
## Contact
|
|
24
|
+
|
|
25
|
+
For privacy questions: **privacy@ansvar.eu**
|
package/README.md
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# Switzerland Farm Safety MCP
|
|
2
|
+
|
|
3
|
+
Machine-readable Swiss farm workplace safety data via the [Model Context Protocol](https://modelcontextprotocol.io).
|
|
4
|
+
|
|
5
|
+
Covers BUL/SPAA safety rules (lebenswichtige Regeln), Suva occupational safety requirements, EKAS Branchenloesung Landwirtschaft, Agriss accident statistics, machinery safety (ROPS, MFK, PTO guards), chemical exposure (PSM, MAK values), young worker restrictions (Jugendarbeitsschutz), and accident reporting obligations.
|
|
6
|
+
|
|
7
|
+
## Quick Start
|
|
8
|
+
|
|
9
|
+
### npx (stdio — zero install)
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npx -y @ansvar/ch-farm-safety-mcp
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### Docker
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
docker run -p 3000:3000 ghcr.io/ansvar-systems/ch-farm-safety-mcp:latest
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Streamable HTTP (remote)
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
https://mcp.ansvar.eu/ch-farm-safety/mcp
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
No authentication required. Rate-limited to fair use.
|
|
28
|
+
|
|
29
|
+
### Claude Desktop / Cursor
|
|
30
|
+
|
|
31
|
+
Add to your MCP client config:
|
|
32
|
+
|
|
33
|
+
```json
|
|
34
|
+
{
|
|
35
|
+
"mcpServers": {
|
|
36
|
+
"ch-farm-safety": {
|
|
37
|
+
"command": "npx",
|
|
38
|
+
"args": ["-y", "@ansvar/ch-farm-safety-mcp"]
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Or use the remote endpoint:
|
|
45
|
+
|
|
46
|
+
```json
|
|
47
|
+
{
|
|
48
|
+
"mcpServers": {
|
|
49
|
+
"ch-farm-safety": {
|
|
50
|
+
"url": "https://mcp.ansvar.eu/ch-farm-safety/mcp"
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Tools
|
|
57
|
+
|
|
58
|
+
10 tools covering Swiss farm workplace safety:
|
|
59
|
+
|
|
60
|
+
| Tool | Description |
|
|
61
|
+
|------|-------------|
|
|
62
|
+
| `about` | Server metadata: name, version, coverage, data sources |
|
|
63
|
+
| `list_sources` | All data sources with authority, URL, license, freshness |
|
|
64
|
+
| `check_data_freshness` | Last ingest date, staleness status, refresh command |
|
|
65
|
+
| `search_safety_rules` | FTS5 search across BUL/Suva/EKAS safety rules |
|
|
66
|
+
| `get_risk_assessment_requirements` | Risk assessment obligations per farm activity (EKAS/VUV) |
|
|
67
|
+
| `get_machinery_safety` | ROPS, Gurtpflicht, MFK, PTO guard requirements by machine type |
|
|
68
|
+
| `get_chemical_safety` | MAK exposure limits, PPE, storage rules by substance |
|
|
69
|
+
| `get_young_worker_rules` | Jugendarbeitsschutz restrictions by age group |
|
|
70
|
+
| `get_accident_reporting` | Reporting deadlines, forms, insurer by severity |
|
|
71
|
+
| `search_bul_guidance` | BUL/SPAA guidance documents, fact sheets, campaigns |
|
|
72
|
+
|
|
73
|
+
Full tool documentation: [TOOLS.md](TOOLS.md)
|
|
74
|
+
|
|
75
|
+
## Data Sources
|
|
76
|
+
|
|
77
|
+
| Source | Authority | Coverage |
|
|
78
|
+
|--------|-----------|----------|
|
|
79
|
+
| [BUL/SPAA](https://www.bul.ch) | Beratungsstelle fuer Unfallverhuetung in der Landwirtschaft | Lebenswichtige Regeln, Merkblaetter, Safe@Work |
|
|
80
|
+
| [Suva](https://www.suva.ch/de-ch/praevention/nach-branche/landwirtschaft) | Schweizerische Unfallversicherungsanstalt | MAK values, PPE, accident reporting |
|
|
81
|
+
| [EKAS](https://www.ekas.admin.ch) | Eidg. Koordinationskommission fuer Arbeitssicherheit | Branchenloesung Landwirtschaft, ASA concept |
|
|
82
|
+
| [Agriss](https://www.bul.ch/de/themen/unfallstatistik) | BUL / Agroscope | Farm accident statistics |
|
|
83
|
+
| [SECO](https://www.seco.admin.ch/seco/de/home/Arbeit/Arbeitsbedingungen/jugendarbeitsschutz.html) | Staatssekretariat fuer Wirtschaft | Young worker protection (ArGV 5) |
|
|
84
|
+
|
|
85
|
+
Coverage details: [COVERAGE.md](COVERAGE.md)
|
|
86
|
+
|
|
87
|
+
## Development
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
npm install
|
|
91
|
+
npm run build
|
|
92
|
+
npm test
|
|
93
|
+
npm run lint
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Ingestion
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
npm run ingest # incremental update
|
|
100
|
+
npm run ingest:full # force full re-ingestion
|
|
101
|
+
npm run ingest:fetch # fetch sources only (no DB write)
|
|
102
|
+
npm run ingest:diff # show changes without applying
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Freshness
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
npm run freshness:check
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Data staleness threshold: 90 days. The `check-freshness.yml` workflow runs weekly and opens an issue if data is stale.
|
|
112
|
+
|
|
113
|
+
## Legal
|
|
114
|
+
|
|
115
|
+
This server provides Swiss farm safety data for informational purposes only. It does not constitute professional safety advice. Always consult BUL/SPAA, Suva, or a qualified safety professional (Sicherheitsfachperson) before implementing safety measures.
|
|
116
|
+
|
|
117
|
+
See [DISCLAIMER.md](DISCLAIMER.md) for the full bilingual disclaimer.
|
|
118
|
+
|
|
119
|
+
## License
|
|
120
|
+
|
|
121
|
+
Apache-2.0 -- see [LICENSE](LICENSE).
|
|
122
|
+
|
|
123
|
+
Data sourced from BUL/SPAA, Suva, EKAS, Agriss, and SECO under Swiss public-sector information principles.
|
|
124
|
+
|
|
125
|
+
## Links
|
|
126
|
+
|
|
127
|
+
- [Ansvar Open Agriculture](https://ansvar.eu/open-agriculture)
|
|
128
|
+
- [MCP Network](https://ansvar.ai/mcp)
|
|
129
|
+
- [SECURITY.md](SECURITY.md) | [PRIVACY.md](PRIVACY.md) | [CHANGELOG.md](CHANGELOG.md)
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Supported Versions
|
|
4
|
+
|
|
5
|
+
| Version | Supported |
|
|
6
|
+
|---------|-----------|
|
|
7
|
+
| 0.1.x | Yes |
|
|
8
|
+
|
|
9
|
+
## Reporting a Vulnerability
|
|
10
|
+
|
|
11
|
+
Report security vulnerabilities to **security@ansvar.eu**.
|
|
12
|
+
|
|
13
|
+
Do **not** open a public GitHub issue for security vulnerabilities.
|
|
14
|
+
|
|
15
|
+
We will acknowledge receipt within 48 hours and provide an initial assessment within 5 business days.
|
|
16
|
+
|
|
17
|
+
## Security Measures
|
|
18
|
+
|
|
19
|
+
- **Read-only database:** The SQLite database is mounted read-only in production containers.
|
|
20
|
+
- **No client data:** This server does not store, process, or transmit client data. All data is pre-ingested public-sector information.
|
|
21
|
+
- **No authentication secrets:** The server requires no API keys, tokens, or credentials.
|
|
22
|
+
- **Container isolation:** Production runs as a non-root user (`nodejs`, UID 1001) with memory limits.
|
|
23
|
+
- **Dependency scanning:** GitHub CodeQL and Gitleaks run on every push and pull request.
|
|
24
|
+
- **GHCR image builds:** Images are built via CI/CD only, signed with GitHub Actions OIDC provenance.
|
|
25
|
+
- **npm provenance:** Published packages include npm provenance attestation.
|