@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.
Files changed (109) hide show
  1. package/.github/workflows/check-freshness.yml +53 -0
  2. package/.github/workflows/ci.yml +21 -0
  3. package/.github/workflows/codeql.yml +30 -0
  4. package/.github/workflows/ghcr-build.yml +45 -0
  5. package/.github/workflows/gitleaks.yml +24 -0
  6. package/.github/workflows/ingest.yml +67 -0
  7. package/.github/workflows/publish.yml +24 -0
  8. package/CHANGELOG.md +23 -0
  9. package/CODEOWNERS +1 -0
  10. package/COVERAGE.md +54 -0
  11. package/DISCLAIMER.md +51 -0
  12. package/Dockerfile +26 -0
  13. package/LICENSE +17 -0
  14. package/PRIVACY.md +25 -0
  15. package/README.md +129 -0
  16. package/SECURITY.md +25 -0
  17. package/TOOLS.md +140 -0
  18. package/data/coverage.json +22 -0
  19. package/data/database.db +0 -0
  20. package/data/sources.yml +36 -0
  21. package/dist/db.d.ts +25 -0
  22. package/dist/db.d.ts.map +1 -0
  23. package/dist/db.js +200 -0
  24. package/dist/db.js.map +1 -0
  25. package/dist/http-server.d.ts +2 -0
  26. package/dist/http-server.d.ts.map +1 -0
  27. package/dist/http-server.js +250 -0
  28. package/dist/http-server.js.map +1 -0
  29. package/dist/jurisdiction.d.ts +18 -0
  30. package/dist/jurisdiction.d.ts.map +1 -0
  31. package/dist/jurisdiction.js +16 -0
  32. package/dist/jurisdiction.js.map +1 -0
  33. package/dist/metadata.d.ts +10 -0
  34. package/dist/metadata.d.ts.map +1 -0
  35. package/dist/metadata.js +20 -0
  36. package/dist/metadata.js.map +1 -0
  37. package/dist/server.d.ts +3 -0
  38. package/dist/server.d.ts.map +1 -0
  39. package/dist/server.js +196 -0
  40. package/dist/server.js.map +1 -0
  41. package/dist/tools/about.d.ts +15 -0
  42. package/dist/tools/about.d.ts.map +1 -0
  43. package/dist/tools/about.js +27 -0
  44. package/dist/tools/about.js.map +1 -0
  45. package/dist/tools/check-freshness.d.ts +15 -0
  46. package/dist/tools/check-freshness.d.ts.map +1 -0
  47. package/dist/tools/check-freshness.js +26 -0
  48. package/dist/tools/check-freshness.js.map +1 -0
  49. package/dist/tools/get-accident-reporting.d.ts +49 -0
  50. package/dist/tools/get-accident-reporting.d.ts.map +1 -0
  51. package/dist/tools/get-accident-reporting.js +31 -0
  52. package/dist/tools/get-accident-reporting.js.map +1 -0
  53. package/dist/tools/get-chemical-safety.d.ts +47 -0
  54. package/dist/tools/get-chemical-safety.d.ts.map +1 -0
  55. package/dist/tools/get-chemical-safety.js +31 -0
  56. package/dist/tools/get-chemical-safety.js.map +1 -0
  57. package/dist/tools/get-machinery-safety.d.ts +46 -0
  58. package/dist/tools/get-machinery-safety.d.ts.map +1 -0
  59. package/dist/tools/get-machinery-safety.js +31 -0
  60. package/dist/tools/get-machinery-safety.js.map +1 -0
  61. package/dist/tools/get-risk-assessment-requirements.d.ts +47 -0
  62. package/dist/tools/get-risk-assessment-requirements.d.ts.map +1 -0
  63. package/dist/tools/get-risk-assessment-requirements.js +31 -0
  64. package/dist/tools/get-risk-assessment-requirements.js.map +1 -0
  65. package/dist/tools/get-young-worker-rules.d.ts +47 -0
  66. package/dist/tools/get-young-worker-rules.d.ts.map +1 -0
  67. package/dist/tools/get-young-worker-rules.js +31 -0
  68. package/dist/tools/get-young-worker-rules.js.map +1 -0
  69. package/dist/tools/list-sources.d.ts +18 -0
  70. package/dist/tools/list-sources.d.ts.map +1 -0
  71. package/dist/tools/list-sources.js +51 -0
  72. package/dist/tools/list-sources.js.map +1 -0
  73. package/dist/tools/search-bul-guidance.d.ts +23 -0
  74. package/dist/tools/search-bul-guidance.d.ts.map +1 -0
  75. package/dist/tools/search-bul-guidance.js +35 -0
  76. package/dist/tools/search-bul-guidance.js.map +1 -0
  77. package/dist/tools/search-safety-rules.d.ts +25 -0
  78. package/dist/tools/search-safety-rules.d.ts.map +1 -0
  79. package/dist/tools/search-safety-rules.js +26 -0
  80. package/dist/tools/search-safety-rules.js.map +1 -0
  81. package/docker-compose.yml +12 -0
  82. package/eslint.config.js +27 -0
  83. package/package.json +54 -0
  84. package/scripts/ingest.ts +879 -0
  85. package/server.json +31 -0
  86. package/src/db.ts +241 -0
  87. package/src/http-server.ts +282 -0
  88. package/src/jurisdiction.ts +30 -0
  89. package/src/metadata.ts +30 -0
  90. package/src/server.ts +219 -0
  91. package/src/tools/about.ts +28 -0
  92. package/src/tools/check-freshness.ts +42 -0
  93. package/src/tools/get-accident-reporting.ts +52 -0
  94. package/src/tools/get-chemical-safety.ts +52 -0
  95. package/src/tools/get-machinery-safety.ts +52 -0
  96. package/src/tools/get-risk-assessment-requirements.ts +52 -0
  97. package/src/tools/get-young-worker-rules.ts +52 -0
  98. package/src/tools/list-sources.ts +65 -0
  99. package/src/tools/search-bul-guidance.ts +51 -0
  100. package/src/tools/search-safety-rules.ts +35 -0
  101. package/tests/db.test.ts +121 -0
  102. package/tests/helpers/seed-db.ts +134 -0
  103. package/tests/jurisdiction.test.ts +54 -0
  104. package/tests/tools/about.test.ts +44 -0
  105. package/tests/tools/check-freshness.test.ts +68 -0
  106. package/tests/tools/list-sources.test.ts +75 -0
  107. package/tests/tools/search-safety-rules.test.ts +75 -0
  108. package/tsconfig.json +19 -0
  109. package/vitest.config.ts +9 -0
@@ -0,0 +1,25 @@
1
+ import { type Database } from '../db.js';
2
+ interface SearchArgs {
3
+ query: string;
4
+ topic?: string;
5
+ jurisdiction?: string;
6
+ limit?: number;
7
+ }
8
+ export declare function handleSearchSafetyRules(db: Database, args: SearchArgs): {
9
+ error: string;
10
+ supported: readonly string[];
11
+ message: string;
12
+ } | {
13
+ query: string;
14
+ jurisdiction: "CH";
15
+ results_count: number;
16
+ results: {
17
+ title: string;
18
+ body: string;
19
+ area: string;
20
+ relevance_rank: number;
21
+ }[];
22
+ _meta: import("../metadata.js").Meta;
23
+ };
24
+ export {};
25
+ //# sourceMappingURL=search-safety-rules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-safety-rules.d.ts","sourceRoot":"","sources":["../../src/tools/search-safety-rules.ts"],"names":[],"mappings":"AAEA,OAAO,EAAa,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEpD,UAAU,UAAU;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU;;;;;;;;;;;;;;;EAuBrE"}
@@ -0,0 +1,26 @@
1
+ import { buildMeta } from '../metadata.js';
2
+ import { validateJurisdiction } from '../jurisdiction.js';
3
+ import { ftsSearch } from '../db.js';
4
+ export function handleSearchSafetyRules(db, args) {
5
+ const jv = validateJurisdiction(args.jurisdiction);
6
+ if (!jv.valid)
7
+ return jv.error;
8
+ const limit = Math.min(args.limit ?? 20, 50);
9
+ let results = ftsSearch(db, args.query, limit);
10
+ if (args.topic) {
11
+ results = results.filter(r => r.area.toLowerCase() === args.topic.toLowerCase());
12
+ }
13
+ return {
14
+ query: args.query,
15
+ jurisdiction: jv.jurisdiction,
16
+ results_count: results.length,
17
+ results: results.map(r => ({
18
+ title: r.title,
19
+ body: r.body,
20
+ area: r.area,
21
+ relevance_rank: r.rank,
22
+ })),
23
+ _meta: buildMeta(),
24
+ };
25
+ }
26
+ //# sourceMappingURL=search-safety-rules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-safety-rules.js","sourceRoot":"","sources":["../../src/tools/search-safety-rules.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAiB,MAAM,UAAU,CAAC;AASpD,MAAM,UAAU,uBAAuB,CAAC,EAAY,EAAE,IAAgB;IACpE,MAAM,EAAE,GAAG,oBAAoB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACnD,IAAI,CAAC,EAAE,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC,KAAK,CAAC;IAE/B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IAC7C,IAAI,OAAO,GAAG,SAAS,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAE/C,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,KAAM,CAAC,WAAW,EAAE,CAAC,CAAC;IACpF,CAAC;IAED,OAAO;QACL,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,YAAY,EAAE,EAAE,CAAC,YAAY;QAC7B,aAAa,EAAE,OAAO,CAAC,MAAM;QAC7B,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACzB,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,cAAc,EAAE,CAAC,CAAC,IAAI;SACvB,CAAC,CAAC;QACH,KAAK,EAAE,SAAS,EAAE;KACnB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,12 @@
1
+ services:
2
+ ch-farm-safety-mcp:
3
+ build: .
4
+ ports:
5
+ - "3000:3000"
6
+ environment:
7
+ - NODE_ENV=production
8
+ - PORT=3000
9
+ read_only: false
10
+ mem_limit: 128m
11
+ cpus: 0.5
12
+ restart: unless-stopped
@@ -0,0 +1,27 @@
1
+ import tseslint from '@typescript-eslint/eslint-plugin';
2
+ import tsparser from '@typescript-eslint/parser';
3
+
4
+ export default [
5
+ {
6
+ files: ['src/**/*.ts', 'tests/**/*.ts'],
7
+ languageOptions: {
8
+ parser: tsparser,
9
+ parserOptions: {
10
+ ecmaVersion: 2022,
11
+ sourceType: 'module',
12
+ },
13
+ },
14
+ plugins: {
15
+ '@typescript-eslint': tseslint,
16
+ },
17
+ rules: {
18
+ ...tseslint.configs.recommended.rules,
19
+ '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
20
+ '@typescript-eslint/no-explicit-any': 'warn',
21
+ 'no-console': ['warn', { allow: ['warn', 'error'] }],
22
+ },
23
+ },
24
+ {
25
+ ignores: ['dist/', 'node_modules/', '*.js', '!eslint.config.js'],
26
+ },
27
+ ];
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@ansvar/ch-farm-safety-mcp",
3
+ "mcpName": "io.github.ansvar-systems/ch-farm-safety",
4
+ "version": "0.1.0",
5
+ "description": "Swiss farm workplace safety via MCP -- BUL/SPAA rules, Suva requirements, EKAS Branchenloesung, Agriss statistics, machinery safety, chemical exposure",
6
+ "type": "module",
7
+ "main": "dist/server.js",
8
+ "bin": {
9
+ "ch-farm-safety-mcp": "dist/server.js"
10
+ },
11
+ "scripts": {
12
+ "build": "tsc",
13
+ "dev": "tsx watch src/server.ts",
14
+ "start": "node dist/server.js",
15
+ "start:http": "node dist/http-server.js",
16
+ "test": "vitest run",
17
+ "test:watch": "vitest",
18
+ "lint": "eslint src/ tests/",
19
+ "typecheck": "tsc --noEmit",
20
+ "ingest": "tsx scripts/ingest.ts",
21
+ "ingest:fetch": "tsx scripts/ingest.ts --fetch-only",
22
+ "ingest:diff": "tsx scripts/ingest.ts --diff-only",
23
+ "ingest:full": "tsx scripts/ingest.ts --force",
24
+ "build:db": "tsx scripts/build-db.ts",
25
+ "freshness:check": "tsx scripts/check-freshness.ts",
26
+ "coverage:update": "tsx scripts/update-coverage.ts"
27
+ },
28
+ "keywords": ["mcp", "agriculture", "safety", "bul", "suva", "farming", "workplace-safety", "switzerland"],
29
+ "author": "Ansvar Systems <info@ansvar.eu>",
30
+ "license": "Apache-2.0",
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "https://github.com/Ansvar-Systems/ch-farm-safety-mcp"
34
+ },
35
+ "homepage": "https://ansvar.eu/open-agriculture",
36
+ "engines": {
37
+ "node": ">=20"
38
+ },
39
+ "dependencies": {
40
+ "@modelcontextprotocol/sdk": "^1.12.0",
41
+ "better-sqlite3": "^11.0.0",
42
+ "zod": "^3.23.0"
43
+ },
44
+ "devDependencies": {
45
+ "@types/better-sqlite3": "^7.6.0",
46
+ "@types/node": "^20.0.0",
47
+ "@typescript-eslint/eslint-plugin": "^8.0.0",
48
+ "@typescript-eslint/parser": "^8.0.0",
49
+ "eslint": "^9.0.0",
50
+ "tsx": "^4.0.0",
51
+ "typescript": "^5.5.0",
52
+ "vitest": "^2.0.0"
53
+ }
54
+ }