@ansvar/ch-livestock-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 (113) hide show
  1. package/.github/workflows/check-freshness.yml +52 -0
  2. package/.github/workflows/ci.yml +21 -0
  3. package/.github/workflows/codeql.yml +31 -0
  4. package/.github/workflows/ghcr-build.yml +45 -0
  5. package/.github/workflows/gitleaks.yml +23 -0
  6. package/.github/workflows/ingest.yml +58 -0
  7. package/.github/workflows/publish.yml +24 -0
  8. package/CHANGELOG.md +24 -0
  9. package/CODEOWNERS +1 -0
  10. package/COVERAGE.md +62 -0
  11. package/DISCLAIMER.md +41 -0
  12. package/Dockerfile +26 -0
  13. package/LICENSE +17 -0
  14. package/PRIVACY.md +28 -0
  15. package/README.md +145 -0
  16. package/SECURITY.md +33 -0
  17. package/TOOLS.md +261 -0
  18. package/data/coverage.json +23 -0
  19. package/data/database.db +0 -0
  20. package/data/sources.yml +29 -0
  21. package/dist/db.d.ts +26 -0
  22. package/dist/db.d.ts.map +1 -0
  23. package/dist/db.js +220 -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 +294 -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 +21 -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 +240 -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-breeding-guidance.d.ts +37 -0
  50. package/dist/tools/get-breeding-guidance.d.ts.map +1 -0
  51. package/dist/tools/get-breeding-guidance.js +39 -0
  52. package/dist/tools/get-breeding-guidance.js.map +1 -0
  53. package/dist/tools/get-feed-requirements.d.ts +40 -0
  54. package/dist/tools/get-feed-requirements.d.ts.map +1 -0
  55. package/dist/tools/get-feed-requirements.js +35 -0
  56. package/dist/tools/get-feed-requirements.js.map +1 -0
  57. package/dist/tools/get-housing-requirements.d.ts +39 -0
  58. package/dist/tools/get-housing-requirements.d.ts.map +1 -0
  59. package/dist/tools/get-housing-requirements.js +35 -0
  60. package/dist/tools/get-housing-requirements.js.map +1 -0
  61. package/dist/tools/get-movement-rules.d.ts +36 -0
  62. package/dist/tools/get-movement-rules.d.ts.map +1 -0
  63. package/dist/tools/get-movement-rules.js +31 -0
  64. package/dist/tools/get-movement-rules.js.map +1 -0
  65. package/dist/tools/get-stocking-density.d.ts +37 -0
  66. package/dist/tools/get-stocking-density.d.ts.map +1 -0
  67. package/dist/tools/get-stocking-density.js +35 -0
  68. package/dist/tools/get-stocking-density.js.map +1 -0
  69. package/dist/tools/get-welfare-standards.d.ts +38 -0
  70. package/dist/tools/get-welfare-standards.d.ts.map +1 -0
  71. package/dist/tools/get-welfare-standards.js +32 -0
  72. package/dist/tools/get-welfare-standards.js.map +1 -0
  73. package/dist/tools/list-sources.d.ts +18 -0
  74. package/dist/tools/list-sources.d.ts.map +1 -0
  75. package/dist/tools/list-sources.js +51 -0
  76. package/dist/tools/list-sources.js.map +1 -0
  77. package/dist/tools/search-animal-health.d.ts +28 -0
  78. package/dist/tools/search-animal-health.d.ts.map +1 -0
  79. package/dist/tools/search-animal-health.js +33 -0
  80. package/dist/tools/search-animal-health.js.map +1 -0
  81. package/dist/tools/search-livestock-guidance.d.ts +27 -0
  82. package/dist/tools/search-livestock-guidance.d.ts.map +1 -0
  83. package/dist/tools/search-livestock-guidance.js +25 -0
  84. package/dist/tools/search-livestock-guidance.js.map +1 -0
  85. package/docker-compose.yml +12 -0
  86. package/eslint.config.js +27 -0
  87. package/package.json +54 -0
  88. package/scripts/ingest.ts +553 -0
  89. package/server.json +10 -0
  90. package/src/db.ts +268 -0
  91. package/src/http-server.ts +327 -0
  92. package/src/jurisdiction.ts +30 -0
  93. package/src/metadata.ts +31 -0
  94. package/src/server.ts +264 -0
  95. package/src/tools/about.ts +28 -0
  96. package/src/tools/check-freshness.ts +42 -0
  97. package/src/tools/get-breeding-guidance.ts +53 -0
  98. package/src/tools/get-feed-requirements.ts +53 -0
  99. package/src/tools/get-housing-requirements.ts +52 -0
  100. package/src/tools/get-movement-rules.ts +45 -0
  101. package/src/tools/get-stocking-density.ts +52 -0
  102. package/src/tools/get-welfare-standards.ts +47 -0
  103. package/src/tools/list-sources.ts +65 -0
  104. package/src/tools/search-animal-health.ts +48 -0
  105. package/src/tools/search-livestock-guidance.ts +33 -0
  106. package/tests/db.test.ts +96 -0
  107. package/tests/helpers/seed-db.ts +97 -0
  108. package/tests/jurisdiction.test.ts +41 -0
  109. package/tests/tools/about.test.ts +32 -0
  110. package/tests/tools/check-freshness.test.ts +55 -0
  111. package/tests/tools/list-sources.test.ts +56 -0
  112. package/tests/tools/search-livestock-guidance.test.ts +63 -0
  113. package/tsconfig.json +19 -0
@@ -0,0 +1,18 @@
1
+ import { buildMeta } from '../metadata.js';
2
+ import type { Database } from '../db.js';
3
+ interface Source {
4
+ name: string;
5
+ authority: string;
6
+ official_url: string;
7
+ retrieval_method: string;
8
+ update_frequency: string;
9
+ license: string;
10
+ coverage: string;
11
+ last_retrieved?: string;
12
+ }
13
+ export declare function handleListSources(db: Database): {
14
+ sources: Source[];
15
+ _meta: ReturnType<typeof buildMeta>;
16
+ };
17
+ export {};
18
+ //# sourceMappingURL=list-sources.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-sources.d.ts","sourceRoot":"","sources":["../../src/tools/list-sources.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,UAAU,MAAM;IACd,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,QAAQ,GAAG;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,KAAK,EAAE,UAAU,CAAC,OAAO,SAAS,CAAC,CAAA;CAAE,CAkD1G"}
@@ -0,0 +1,51 @@
1
+ import { buildMeta } from '../metadata.js';
2
+ export function handleListSources(db) {
3
+ const lastIngest = db.get('SELECT value FROM db_metadata WHERE key = ?', ['last_ingest']);
4
+ const sources = [
5
+ {
6
+ name: 'Tierschutzverordnung (TSchV, SR 455.1)',
7
+ authority: 'Bundesamt fuer Lebensmittelsicherheit und Veterinaerwesen (BLV)',
8
+ official_url: 'https://www.fedlex.admin.ch/eli/cc/2008/416/de',
9
+ retrieval_method: 'PDF_EXTRACT',
10
+ update_frequency: 'periodic (amended as needed)',
11
+ license: 'Swiss Federal Administration — free reuse',
12
+ coverage: 'Minimum welfare standards per species, space requirements, housing, transport, slaughter',
13
+ last_retrieved: lastIngest?.value,
14
+ },
15
+ {
16
+ name: 'Direktzahlungsverordnung (DZV) — RAUS/BTS-Programme',
17
+ authority: 'Bundesamt fuer Landwirtschaft (BLW)',
18
+ official_url: 'https://www.blw.admin.ch/blw/de/home/instrumente/direktzahlungen/produktionssystembeitraege/tierwohlbeitraege.html',
19
+ retrieval_method: 'PDF_EXTRACT',
20
+ update_frequency: 'annual (with DZV updates)',
21
+ license: 'Swiss Federal Administration — free reuse',
22
+ coverage: 'RAUS outdoor access requirements, BTS housing standards, payment rates per GVE',
23
+ last_retrieved: lastIngest?.value,
24
+ },
25
+ {
26
+ name: 'Tierverkehrsdatenbank (TVD)',
27
+ authority: 'Identitas AG / BLV',
28
+ official_url: 'https://www.identitas.ch/tvd',
29
+ retrieval_method: 'PUBLIC_DOCS',
30
+ update_frequency: 'continuous (registration rules updated periodically)',
31
+ license: 'Public regulatory information',
32
+ coverage: 'Animal registration, ear tags, movement reporting, species coverage',
33
+ last_retrieved: lastIngest?.value,
34
+ },
35
+ {
36
+ name: 'Zuchtorganisationen (Braunvieh Schweiz, swissherdbook, Mutterkuh Schweiz, Suisseporcs)',
37
+ authority: 'Various breed associations',
38
+ official_url: 'https://www.braunvieh.ch',
39
+ retrieval_method: 'PUBLIC_DOCS',
40
+ update_frequency: 'annual',
41
+ license: 'Public breed information',
42
+ coverage: 'Swiss cattle, pig, sheep, goat, and horse breeds — characteristics, purpose, regional distribution',
43
+ last_retrieved: lastIngest?.value,
44
+ },
45
+ ];
46
+ return {
47
+ sources,
48
+ _meta: buildMeta(),
49
+ };
50
+ }
51
+ //# sourceMappingURL=list-sources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-sources.js","sourceRoot":"","sources":["../../src/tools/list-sources.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAc3C,MAAM,UAAU,iBAAiB,CAAC,EAAY;IAC5C,MAAM,UAAU,GAAG,EAAE,CAAC,GAAG,CAAoB,6CAA6C,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC;IAE7G,MAAM,OAAO,GAAa;QACxB;YACE,IAAI,EAAE,wCAAwC;YAC9C,SAAS,EAAE,iEAAiE;YAC5E,YAAY,EAAE,gDAAgD;YAC9D,gBAAgB,EAAE,aAAa;YAC/B,gBAAgB,EAAE,8BAA8B;YAChD,OAAO,EAAE,2CAA2C;YACpD,QAAQ,EAAE,0FAA0F;YACpG,cAAc,EAAE,UAAU,EAAE,KAAK;SAClC;QACD;YACE,IAAI,EAAE,qDAAqD;YAC3D,SAAS,EAAE,qCAAqC;YAChD,YAAY,EAAE,oHAAoH;YAClI,gBAAgB,EAAE,aAAa;YAC/B,gBAAgB,EAAE,2BAA2B;YAC7C,OAAO,EAAE,2CAA2C;YACpD,QAAQ,EAAE,gFAAgF;YAC1F,cAAc,EAAE,UAAU,EAAE,KAAK;SAClC;QACD;YACE,IAAI,EAAE,6BAA6B;YACnC,SAAS,EAAE,oBAAoB;YAC/B,YAAY,EAAE,8BAA8B;YAC5C,gBAAgB,EAAE,aAAa;YAC/B,gBAAgB,EAAE,sDAAsD;YACxE,OAAO,EAAE,+BAA+B;YACxC,QAAQ,EAAE,qEAAqE;YAC/E,cAAc,EAAE,UAAU,EAAE,KAAK;SAClC;QACD;YACE,IAAI,EAAE,wFAAwF;YAC9F,SAAS,EAAE,4BAA4B;YACvC,YAAY,EAAE,0BAA0B;YACxC,gBAAgB,EAAE,aAAa;YAC/B,gBAAgB,EAAE,QAAQ;YAC1B,OAAO,EAAE,0BAA0B;YACnC,QAAQ,EAAE,oGAAoG;YAC9G,cAAc,EAAE,UAAU,EAAE,KAAK;SAClC;KACF,CAAC;IAEF,OAAO;QACL,OAAO;QACP,KAAK,EAAE,SAAS,EAAE;KACnB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,28 @@
1
+ import type { Database } from '../db.js';
2
+ interface HealthSearchArgs {
3
+ query: string;
4
+ species?: string;
5
+ jurisdiction?: string;
6
+ }
7
+ export declare function handleSearchAnimalHealth(db: Database, args: HealthSearchArgs): {
8
+ error: string;
9
+ supported: readonly string[];
10
+ message: string;
11
+ } | {
12
+ query: string;
13
+ species_filter: string | null;
14
+ jurisdiction: "CH";
15
+ results_count: number;
16
+ results: {
17
+ id: number;
18
+ species: string;
19
+ condition: string;
20
+ symptoms: string;
21
+ prevention: string;
22
+ regulatory_status: string;
23
+ details: string;
24
+ }[];
25
+ _meta: import("../metadata.js").Meta;
26
+ };
27
+ export {};
28
+ //# sourceMappingURL=search-animal-health.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-animal-health.d.ts","sourceRoot":"","sources":["../../src/tools/search-animal-health.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,UAAU,gBAAgB;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,wBAAwB,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,gBAAgB;;;;;;;;;;YAarE,MAAM;iBAAW,MAAM;mBAAa,MAAM;kBAAY,MAAM;oBACpD,MAAM;2BAAqB,MAAM;iBAAW,MAAM;;;EAuBjE"}
@@ -0,0 +1,33 @@
1
+ import { buildMeta } from '../metadata.js';
2
+ import { validateJurisdiction } from '../jurisdiction.js';
3
+ export function handleSearchAnimalHealth(db, args) {
4
+ const jv = validateJurisdiction(args.jurisdiction);
5
+ if (!jv.valid)
6
+ return jv.error;
7
+ let sql = 'SELECT * FROM animal_health WHERE jurisdiction = ?';
8
+ const params = [jv.jurisdiction];
9
+ if (args.species) {
10
+ sql += ' AND LOWER(species) = LOWER(?)';
11
+ params.push(args.species);
12
+ }
13
+ const all = db.all(sql, params);
14
+ // Filter by query terms (case-insensitive substring match across all text fields)
15
+ const queryLower = args.query.toLowerCase();
16
+ const terms = queryLower.split(/\s+/).filter(t => t.length > 1);
17
+ const filtered = all.filter(row => {
18
+ const text = [row.condition, row.symptoms, row.prevention, row.details, row.regulatory_status]
19
+ .filter(Boolean)
20
+ .join(' ')
21
+ .toLowerCase();
22
+ return terms.some(t => text.includes(t));
23
+ });
24
+ return {
25
+ query: args.query,
26
+ species_filter: args.species ?? null,
27
+ jurisdiction: jv.jurisdiction,
28
+ results_count: filtered.length,
29
+ results: filtered,
30
+ _meta: buildMeta(),
31
+ };
32
+ }
33
+ //# sourceMappingURL=search-animal-health.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-animal-health.js","sourceRoot":"","sources":["../../src/tools/search-animal-health.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAS1D,MAAM,UAAU,wBAAwB,CAAC,EAAY,EAAE,IAAsB;IAC3E,MAAM,EAAE,GAAG,oBAAoB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACnD,IAAI,CAAC,EAAE,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC,KAAK,CAAC;IAE/B,IAAI,GAAG,GAAG,oDAAoD,CAAC;IAC/D,MAAM,MAAM,GAAc,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC;IAE5C,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,GAAG,IAAI,gCAAgC,CAAC;QACxC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC5B,CAAC;IAED,MAAM,GAAG,GAAG,EAAE,CAAC,GAAG,CAGf,GAAG,EAAE,MAAM,CAAC,CAAC;IAEhB,kFAAkF;IAClF,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;IAC5C,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAEhE,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;QAChC,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,iBAAiB,CAAC;aAC3F,MAAM,CAAC,OAAO,CAAC;aACf,IAAI,CAAC,GAAG,CAAC;aACT,WAAW,EAAE,CAAC;QACjB,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,cAAc,EAAE,IAAI,CAAC,OAAO,IAAI,IAAI;QACpC,YAAY,EAAE,EAAE,CAAC,YAAY;QAC7B,aAAa,EAAE,QAAQ,CAAC,MAAM;QAC9B,OAAO,EAAE,QAAQ;QACjB,KAAK,EAAE,SAAS,EAAE;KACnB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,27 @@
1
+ import { type Database } from '../db.js';
2
+ interface SearchArgs {
3
+ query: string;
4
+ species?: string;
5
+ jurisdiction?: string;
6
+ limit?: number;
7
+ }
8
+ export declare function handleSearchLivestockGuidance(db: Database, args: SearchArgs): {
9
+ error: string;
10
+ supported: readonly string[];
11
+ message: string;
12
+ } | {
13
+ query: string;
14
+ species_filter: string | null;
15
+ jurisdiction: "CH";
16
+ results_count: number;
17
+ results: {
18
+ title: string;
19
+ body: string;
20
+ species: string;
21
+ category: string;
22
+ relevance_rank: number;
23
+ }[];
24
+ _meta: import("../metadata.js").Meta;
25
+ };
26
+ export {};
27
+ //# sourceMappingURL=search-livestock-guidance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-livestock-guidance.d.ts","sourceRoot":"","sources":["../../src/tools/search-livestock-guidance.ts"],"names":[],"mappings":"AAEA,OAAO,EAAa,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEpD,UAAU,UAAU;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,6BAA6B,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU;;;;;;;;;;;;;;;;;EAqB3E"}
@@ -0,0 +1,25 @@
1
+ import { buildMeta } from '../metadata.js';
2
+ import { validateJurisdiction } from '../jurisdiction.js';
3
+ import { ftsSearch } from '../db.js';
4
+ export function handleSearchLivestockGuidance(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
+ const results = ftsSearch(db, args.query, limit, args.species);
10
+ return {
11
+ query: args.query,
12
+ species_filter: args.species ?? null,
13
+ jurisdiction: jv.jurisdiction,
14
+ results_count: results.length,
15
+ results: results.map(r => ({
16
+ title: r.title,
17
+ body: r.body,
18
+ species: r.species,
19
+ category: r.category,
20
+ relevance_rank: r.rank,
21
+ })),
22
+ _meta: buildMeta(),
23
+ };
24
+ }
25
+ //# sourceMappingURL=search-livestock-guidance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-livestock-guidance.js","sourceRoot":"","sources":["../../src/tools/search-livestock-guidance.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,6BAA6B,CAAC,EAAY,EAAE,IAAgB;IAC1E,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,MAAM,OAAO,GAAG,SAAS,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IAE/D,OAAO;QACL,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,cAAc,EAAE,IAAI,CAAC,OAAO,IAAI,IAAI;QACpC,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,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,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-livestock-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/', 'ch-crop-nutrients-mcp/'],
26
+ },
27
+ ];
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@ansvar/ch-livestock-mcp",
3
+ "mcpName": "io.github.ansvar-systems/ch-livestock-mcp",
4
+ "version": "0.1.0",
5
+ "description": "Swiss livestock regulations via MCP -- TSchV welfare standards, RAUS/BTS programmes, TVD movement rules, housing requirements, breed data",
6
+ "type": "module",
7
+ "main": "dist/server.js",
8
+ "bin": {
9
+ "ch-livestock-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", "livestock", "animal-welfare", "tierschutz", "farming", "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-livestock-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
+ }