@ansvar/ch-pest-management-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 +49 -0
- package/.github/workflows/ci.yml +21 -0
- package/.github/workflows/codeql.yml +25 -0
- package/.github/workflows/ghcr-build.yml +45 -0
- package/.github/workflows/gitleaks.yml +18 -0
- package/.github/workflows/ingest.yml +59 -0
- package/.github/workflows/publish.yml +24 -0
- package/CHANGELOG.md +16 -0
- package/CODEOWNERS +1 -0
- package/COVERAGE.md +66 -0
- package/DISCLAIMER.md +39 -0
- package/Dockerfile +26 -0
- package/LICENSE +17 -0
- package/PRIVACY.md +23 -0
- package/README.md +98 -0
- package/SECURITY.md +26 -0
- package/TOOLS.md +202 -0
- package/data/coverage.json +34 -0
- package/data/database.db +0 -0
- package/data/sources.yml +57 -0
- package/dist/db.d.ts +26 -0
- package/dist/db.d.ts.map +1 -0
- package/dist/db.js +189 -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 +270 -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 +21 -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 +216 -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-approved-products.d.ts +38 -0
- package/dist/tools/get-approved-products.d.ts.map +1 -0
- package/dist/tools/get-approved-products.js +49 -0
- package/dist/tools/get-approved-products.js.map +1 -0
- package/dist/tools/get-ipm-guidance.d.ts +42 -0
- package/dist/tools/get-ipm-guidance.d.ts.map +1 -0
- package/dist/tools/get-ipm-guidance.js +40 -0
- package/dist/tools/get-ipm-guidance.js.map +1 -0
- package/dist/tools/get-pest-details.d.ts +43 -0
- package/dist/tools/get-pest-details.d.ts.map +1 -0
- package/dist/tools/get-pest-details.js +20 -0
- package/dist/tools/get-pest-details.js.map +1 -0
- package/dist/tools/get-treatments.d.ts +46 -0
- package/dist/tools/get-treatments.d.ts.map +1 -0
- package/dist/tools/get-treatments.js +41 -0
- package/dist/tools/get-treatments.js.map +1 -0
- package/dist/tools/identify-from-symptoms.d.ts +31 -0
- package/dist/tools/identify-from-symptoms.d.ts.map +1 -0
- package/dist/tools/identify-from-symptoms.js +49 -0
- package/dist/tools/identify-from-symptoms.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-crop-threats.d.ts +36 -0
- package/dist/tools/search-crop-threats.d.ts.map +1 -0
- package/dist/tools/search-crop-threats.js +48 -0
- package/dist/tools/search-crop-threats.js.map +1 -0
- package/dist/tools/search-pests.d.ts +31 -0
- package/dist/tools/search-pests.d.ts.map +1 -0
- package/dist/tools/search-pests.js +36 -0
- package/dist/tools/search-pests.js.map +1 -0
- package/docker-compose.yml +12 -0
- package/eslint.config.js +23 -0
- package/package.json +54 -0
- package/scripts/ingest.ts +1037 -0
- package/server.json +71 -0
- package/src/db.ts +230 -0
- package/src/http-server.ts +302 -0
- package/src/jurisdiction.ts +30 -0
- package/src/metadata.ts +31 -0
- package/src/server.ts +239 -0
- package/src/tools/about.ts +28 -0
- package/src/tools/check-freshness.ts +42 -0
- package/src/tools/get-approved-products.ts +68 -0
- package/src/tools/get-ipm-guidance.ts +56 -0
- package/src/tools/get-pest-details.ts +44 -0
- package/src/tools/get-treatments.ts +61 -0
- package/src/tools/identify-from-symptoms.ts +64 -0
- package/src/tools/list-sources.ts +65 -0
- package/src/tools/search-crop-threats.ts +74 -0
- package/src/tools/search-pests.ts +49 -0
- package/tests/db.test.ts +82 -0
- package/tests/helpers/seed-db.ts +187 -0
- package/tests/jurisdiction.test.ts +35 -0
- package/tests/tools/about.test.ts +27 -0
- package/tests/tools/check-freshness.test.ts +58 -0
- package/tests/tools/list-sources.test.ts +57 -0
- package/tests/tools/search-pests.test.ts +64 -0
- package/tsconfig.json +19 -0
package/TOOLS.md
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
# Tools Reference
|
|
2
|
+
|
|
3
|
+
## about
|
|
4
|
+
|
|
5
|
+
Get server metadata: name, version, coverage, data sources, and links.
|
|
6
|
+
|
|
7
|
+
**Parameters:** None
|
|
8
|
+
|
|
9
|
+
**Returns:** Server name, version, jurisdiction, data sources list, tool count, links, disclaimer metadata.
|
|
10
|
+
|
|
11
|
+
**Example:**
|
|
12
|
+
```json
|
|
13
|
+
{ }
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## list_sources
|
|
19
|
+
|
|
20
|
+
List all data sources with authority, URL, license, and freshness info.
|
|
21
|
+
|
|
22
|
+
**Parameters:** None
|
|
23
|
+
|
|
24
|
+
**Returns:** Array of sources, each with `name`, `authority`, `official_url`, `retrieval_method`, `update_frequency`, `license`, `coverage`, `last_retrieved`.
|
|
25
|
+
|
|
26
|
+
**Example:**
|
|
27
|
+
```json
|
|
28
|
+
{ }
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## check_data_freshness
|
|
34
|
+
|
|
35
|
+
Check when data was last ingested, staleness status, and how to trigger a refresh.
|
|
36
|
+
|
|
37
|
+
**Parameters:** None
|
|
38
|
+
|
|
39
|
+
**Returns:**
|
|
40
|
+
|
|
41
|
+
| Field | Type | Description |
|
|
42
|
+
|-------|------|-------------|
|
|
43
|
+
| `status` | string | `fresh`, `stale`, or `unknown` |
|
|
44
|
+
| `last_ingest` | string or null | ISO date of last ingestion |
|
|
45
|
+
| `days_since_ingest` | number or null | Days since last ingestion |
|
|
46
|
+
| `staleness_threshold_days` | number | Threshold (90 days) |
|
|
47
|
+
| `refresh_command` | string | CLI command to trigger re-ingestion |
|
|
48
|
+
|
|
49
|
+
**Example:**
|
|
50
|
+
```json
|
|
51
|
+
{ }
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## search_pests
|
|
57
|
+
|
|
58
|
+
Search pests, diseases, and weeds affecting Swiss crops. Supports German and English queries. Uses tiered FTS5 search (phrase > AND > prefix > stemmed > OR > LIKE fallback).
|
|
59
|
+
|
|
60
|
+
**Parameters:**
|
|
61
|
+
|
|
62
|
+
| Name | Type | Required | Description |
|
|
63
|
+
|------|------|----------|-------------|
|
|
64
|
+
| `query` | string | yes | Free-text search (e.g. "Blattlaeuse Weizen", "Septoria") |
|
|
65
|
+
| `pest_type` | string | no | Filter by type: `insect`, `disease`, or `weed` |
|
|
66
|
+
| `crop` | string | no | Filter by affected crop (e.g. "Winterweizen", "Kartoffeln") |
|
|
67
|
+
| `jurisdiction` | string | no | ISO 3166-1 alpha-2 code (default: CH) |
|
|
68
|
+
| `limit` | number | no | Max results (default: 20, max: 50) |
|
|
69
|
+
|
|
70
|
+
**Returns:** Array of matching pests with `title`, `body`, `pest_type`, `crop_category`, `relevance_rank`.
|
|
71
|
+
|
|
72
|
+
**Example:**
|
|
73
|
+
```json
|
|
74
|
+
{ "query": "Blattlaeuse", "crop": "Winterweizen" }
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## get_pest_details
|
|
80
|
+
|
|
81
|
+
Get full profile for a pest: lifecycle, identification, crops affected, and treatments.
|
|
82
|
+
|
|
83
|
+
**Parameters:**
|
|
84
|
+
|
|
85
|
+
| Name | Type | Required | Description |
|
|
86
|
+
|------|------|----------|-------------|
|
|
87
|
+
| `pest_id` | string | yes | Pest ID from search_pests (e.g. "blattlaeuse", "septoria") |
|
|
88
|
+
| `jurisdiction` | string | no | ISO 3166-1 alpha-2 code (default: CH) |
|
|
89
|
+
|
|
90
|
+
**Returns:** Pest profile with `id`, `name`, `pest_type`, `scientific_name`, `crops_affected` (array), `lifecycle`, `identification`, `damage_description`, plus associated `treatments` array.
|
|
91
|
+
|
|
92
|
+
**Example:**
|
|
93
|
+
```json
|
|
94
|
+
{ "pest_id": "blattlaeuse" }
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## get_treatments
|
|
100
|
+
|
|
101
|
+
Get approved chemical and non-chemical controls for a specific pest. Includes products, active substances, W-numbers, dosage, waiting periods, Pufferstreifen, and OELN alternatives.
|
|
102
|
+
|
|
103
|
+
**Parameters:**
|
|
104
|
+
|
|
105
|
+
| Name | Type | Required | Description |
|
|
106
|
+
|------|------|----------|-------------|
|
|
107
|
+
| `pest_id` | string | yes | Pest ID (e.g. "rapsglanzkaefer", "krautfaeule") |
|
|
108
|
+
| `approach` | string | no | Filter: `chemical`, `biological`, `cultural`, or `mechanical` |
|
|
109
|
+
| `jurisdiction` | string | no | ISO 3166-1 alpha-2 code (default: CH) |
|
|
110
|
+
|
|
111
|
+
**Returns:** Pest info plus array of treatments, each with `approach`, `product_name`, `active_substance`, `w_number`, `dosage`, `waiting_period`, `timing`, `restrictions`, `pufferstreifen`, `notes`.
|
|
112
|
+
|
|
113
|
+
**Example:**
|
|
114
|
+
```json
|
|
115
|
+
{ "pest_id": "krautfaeule", "approach": "chemical" }
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## get_ipm_guidance
|
|
121
|
+
|
|
122
|
+
Get IPM (Integrierter Pflanzenschutz) guidance for a crop: OELN Schadschwellen, monitoring methods, cultural controls, and prognosis systems.
|
|
123
|
+
|
|
124
|
+
**Parameters:**
|
|
125
|
+
|
|
126
|
+
| Name | Type | Required | Description |
|
|
127
|
+
|------|------|----------|-------------|
|
|
128
|
+
| `crop` | string | yes | Crop name (e.g. "Winterweizen", "Kartoffeln", "Reben", "Apfel") |
|
|
129
|
+
| `pest_id` | string | no | Filter to specific pest |
|
|
130
|
+
| `jurisdiction` | string | no | ISO 3166-1 alpha-2 code (default: CH) |
|
|
131
|
+
|
|
132
|
+
**Returns:** Array of guidance entries per pest, each with `threshold` (Schadschwelle), `monitoring_method`, `cultural_controls`, `prognose_system`, `oeln_requirements`.
|
|
133
|
+
|
|
134
|
+
**Example:**
|
|
135
|
+
```json
|
|
136
|
+
{ "crop": "Winterweizen" }
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## search_crop_threats
|
|
142
|
+
|
|
143
|
+
List all pests, diseases, and weeds that threaten a specific crop, with damage thresholds and monitoring advice. Groups results by type (insects, diseases, weeds).
|
|
144
|
+
|
|
145
|
+
**Parameters:**
|
|
146
|
+
|
|
147
|
+
| Name | Type | Required | Description |
|
|
148
|
+
|------|------|----------|-------------|
|
|
149
|
+
| `crop` | string | yes | Crop name (e.g. "Winterweizen", "Winterraps", "Kartoffeln") |
|
|
150
|
+
| `growth_stage` | string | no | Growth stage filter (e.g. "Bestockung", "Bluete") |
|
|
151
|
+
| `jurisdiction` | string | no | ISO 3166-1 alpha-2 code (default: CH) |
|
|
152
|
+
|
|
153
|
+
**Returns:** `total_threats`, breakdown `by_type` (insects/diseases/weeds counts), and `threats` array with `pest_id`, `name`, `pest_type`, `scientific_name`, `damage`, `identification`, `threshold`, `monitoring`, `prognose_system`.
|
|
154
|
+
|
|
155
|
+
**Example:**
|
|
156
|
+
```json
|
|
157
|
+
{ "crop": "Kartoffeln" }
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## identify_from_symptoms
|
|
163
|
+
|
|
164
|
+
Identify a pest, disease, or weed from symptom descriptions. Returns a ranked differential diagnosis.
|
|
165
|
+
|
|
166
|
+
**Parameters:**
|
|
167
|
+
|
|
168
|
+
| Name | Type | Required | Description |
|
|
169
|
+
|------|------|----------|-------------|
|
|
170
|
+
| `symptoms` | string | yes | Symptom description (e.g. "gelbe Flecken auf Weizenblaettern") |
|
|
171
|
+
| `crop` | string | no | Affected crop to narrow results |
|
|
172
|
+
| `season` | string | no | Time of year (e.g. "Fruehling", "Sommer") |
|
|
173
|
+
| `jurisdiction` | string | no | ISO 3166-1 alpha-2 code (default: CH) |
|
|
174
|
+
|
|
175
|
+
**Returns:** `possible_matches` array with `pest_id`, `name`, `pest_type`, `scientific_name`, `identification`, `damage_description`, `crops_affected`, plus a recommendation to consult the cantonal Pflanzenschutzfachstelle for uncertain cases.
|
|
176
|
+
|
|
177
|
+
**Example:**
|
|
178
|
+
```json
|
|
179
|
+
{ "symptoms": "Frass an Rapsblueten", "crop": "Winterraps" }
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## get_approved_products
|
|
185
|
+
|
|
186
|
+
Search approved plant protection products (Pflanzenschutzmittel) from the BLW Verzeichnis. At least one filter is recommended.
|
|
187
|
+
|
|
188
|
+
**Parameters:**
|
|
189
|
+
|
|
190
|
+
| Name | Type | Required | Description |
|
|
191
|
+
|------|------|----------|-------------|
|
|
192
|
+
| `active_substance` | string | no | Active substance name (e.g. "Glyphosat", "Mancozeb") |
|
|
193
|
+
| `target_pest` | string | no | Target organism (e.g. "Blattlaeuse", "Pilzkrankheiten") |
|
|
194
|
+
| `crop` | string | no | Target crop (e.g. "Winterweizen", "Reben") |
|
|
195
|
+
| `jurisdiction` | string | no | ISO 3166-1 alpha-2 code (default: CH) |
|
|
196
|
+
|
|
197
|
+
**Returns:** Array of products with `w_number`, `product_name`, `active_substance`, `product_type`, `crops`, `target_organisms`, `auflagen`, `wartefrist`, `dosage`, `application_method`, `spe3_buffer`, `aktionsplan_status`. Always includes a warning to verify current authorisation on psm.admin.ch.
|
|
198
|
+
|
|
199
|
+
**Example:**
|
|
200
|
+
```json
|
|
201
|
+
{ "active_substance": "Spinosad", "crop": "Kartoffeln" }
|
|
202
|
+
```
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"server": "ch-pest-management-mcp",
|
|
3
|
+
"jurisdiction": "CH",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"last_ingest": "2026-04-05",
|
|
6
|
+
"data": {
|
|
7
|
+
"pests": 23,
|
|
8
|
+
"pests_insects": 9,
|
|
9
|
+
"pests_diseases": 8,
|
|
10
|
+
"pests_weeds": 6,
|
|
11
|
+
"treatments": 30,
|
|
12
|
+
"ipm_guidance": 12,
|
|
13
|
+
"approved_products": 14,
|
|
14
|
+
"prognosis_systems": [
|
|
15
|
+
"PhytoPRE",
|
|
16
|
+
"SOPRA",
|
|
17
|
+
"FusaProg",
|
|
18
|
+
"VitiMeteo"
|
|
19
|
+
],
|
|
20
|
+
"crop_categories": [
|
|
21
|
+
"feldbau",
|
|
22
|
+
"rebbau",
|
|
23
|
+
"obstbau",
|
|
24
|
+
"gemuese"
|
|
25
|
+
]
|
|
26
|
+
},
|
|
27
|
+
"tools": 10,
|
|
28
|
+
"sources": [
|
|
29
|
+
"BLW Pflanzenschutzmittelverzeichnis (psm.admin.ch)",
|
|
30
|
+
"Agroscope Pflanzenschutzempfehlungen",
|
|
31
|
+
"AGRIDEA OELN-Checklisten",
|
|
32
|
+
"Aktionsplan Pflanzenschutzmittel"
|
|
33
|
+
]
|
|
34
|
+
}
|
package/data/database.db
ADDED
|
Binary file
|
package/data/sources.yml
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Data sources for ch-pest-management-mcp
|
|
2
|
+
sources:
|
|
3
|
+
- name: BLW Pflanzenschutzmittelverzeichnis
|
|
4
|
+
authority: Bundesamt fuer Landwirtschaft (BLW)
|
|
5
|
+
url: https://www.psm.admin.ch/de/produkte
|
|
6
|
+
license: Swiss Federal Administration — free reuse
|
|
7
|
+
update_frequency: continuous (products added/removed)
|
|
8
|
+
last_retrieved: "2026-04-05"
|
|
9
|
+
|
|
10
|
+
- name: Agroscope Pflanzenschutzempfehlungen
|
|
11
|
+
authority: Agroscope
|
|
12
|
+
url: https://www.agroscope.admin.ch/agroscope/de/home/themen/pflanzenbau/pflanzenschutz.html
|
|
13
|
+
license: Swiss Federal Administration — free reuse
|
|
14
|
+
update_frequency: annual
|
|
15
|
+
last_retrieved: "2026-04-05"
|
|
16
|
+
|
|
17
|
+
- name: AGRIDEA OELN-Pflanzenschutz-Checklisten
|
|
18
|
+
authority: AGRIDEA
|
|
19
|
+
url: https://www.agridea.ch/de/themen/pflanzenbau/pflanzenschutz/
|
|
20
|
+
license: Public advisory material
|
|
21
|
+
update_frequency: annual
|
|
22
|
+
last_retrieved: "2026-04-05"
|
|
23
|
+
|
|
24
|
+
- name: Aktionsplan Pflanzenschutzmittel
|
|
25
|
+
authority: Bundesrat / BLW
|
|
26
|
+
url: https://www.blw.admin.ch/blw/de/home/nachhaltige-produktion/pflanzenschutz/aktionsplan.html
|
|
27
|
+
license: Swiss Federal Administration — free reuse
|
|
28
|
+
update_frequency: periodic (adopted 2017, targets to 2027)
|
|
29
|
+
last_retrieved: "2026-04-05"
|
|
30
|
+
|
|
31
|
+
- name: PhytoPRE Prognosemodell
|
|
32
|
+
authority: Agroscope
|
|
33
|
+
url: https://www.phytopre.ch
|
|
34
|
+
license: Public access
|
|
35
|
+
update_frequency: real-time (growing season)
|
|
36
|
+
last_retrieved: "2026-04-05"
|
|
37
|
+
|
|
38
|
+
- name: SOPRA Schaedlingsprognose
|
|
39
|
+
authority: Agroscope
|
|
40
|
+
url: https://www.sopra.info
|
|
41
|
+
license: Public access
|
|
42
|
+
update_frequency: real-time (growing season)
|
|
43
|
+
last_retrieved: "2026-04-05"
|
|
44
|
+
|
|
45
|
+
- name: FusaProg Fusariumprognose
|
|
46
|
+
authority: Agroscope / Meteotest
|
|
47
|
+
url: https://www.fusaprog.ch
|
|
48
|
+
license: Public access
|
|
49
|
+
update_frequency: real-time (growing season)
|
|
50
|
+
last_retrieved: "2026-04-05"
|
|
51
|
+
|
|
52
|
+
- name: VitiMeteo Rebenprognose
|
|
53
|
+
authority: Agroscope Changins
|
|
54
|
+
url: https://www.vitimeteo.info
|
|
55
|
+
license: Public access
|
|
56
|
+
update_frequency: real-time (growing season)
|
|
57
|
+
last_retrieved: "2026-04-05"
|
package/dist/db.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import BetterSqlite3 from 'better-sqlite3';
|
|
2
|
+
export interface Database {
|
|
3
|
+
get<T>(sql: string, params?: unknown[]): T | undefined;
|
|
4
|
+
all<T>(sql: string, params?: unknown[]): T[];
|
|
5
|
+
run(sql: string, params?: unknown[]): void;
|
|
6
|
+
close(): void;
|
|
7
|
+
readonly instance: BetterSqlite3.Database;
|
|
8
|
+
}
|
|
9
|
+
export declare function createDatabase(dbPath?: string): Database;
|
|
10
|
+
export declare function ftsSearch(db: Database, query: string, limit?: number): {
|
|
11
|
+
title: string;
|
|
12
|
+
body: string;
|
|
13
|
+
pest_type: string;
|
|
14
|
+
crop_category: string;
|
|
15
|
+
jurisdiction: string;
|
|
16
|
+
rank: number;
|
|
17
|
+
}[];
|
|
18
|
+
/**
|
|
19
|
+
* Tiered FTS5 search with automatic fallback.
|
|
20
|
+
* Tiers: exact phrase -> AND -> prefix -> stemmed prefix -> OR -> LIKE
|
|
21
|
+
*/
|
|
22
|
+
export declare function tieredFtsSearch(db: Database, table: string, columns: string[], query: string, limit?: number): {
|
|
23
|
+
tier: string;
|
|
24
|
+
results: Record<string, unknown>[];
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=db.d.ts.map
|
package/dist/db.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,gBAAgB,CAAC;AAI3C,MAAM,WAAW,QAAQ;IACvB,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,GAAG,SAAS,CAAC;IACvD,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,CAAC;IAC7C,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC3C,KAAK,IAAI,IAAI,CAAC;IACd,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC,QAAQ,CAAC;CAC3C;AAED,wBAAgB,cAAc,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,CA4BxD;AAmFD,wBAAgB,SAAS,CACvB,EAAE,EAAE,QAAQ,EACZ,KAAK,EAAE,MAAM,EACb,KAAK,GAAE,MAAW,GACjB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,CAGjH;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,EAAE,EAAE,QAAQ,EACZ,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EAAE,EACjB,KAAK,EAAE,MAAM,EACb,KAAK,GAAE,MAAW,GACjB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAA;CAAE,CA4DtD"}
|
package/dist/db.js
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import BetterSqlite3 from 'better-sqlite3';
|
|
2
|
+
import { join, dirname } from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
export function createDatabase(dbPath) {
|
|
5
|
+
const resolvedPath = dbPath ??
|
|
6
|
+
join(dirname(fileURLToPath(import.meta.url)), '..', 'data', 'database.db');
|
|
7
|
+
const db = new BetterSqlite3(resolvedPath);
|
|
8
|
+
db.pragma('journal_mode = DELETE');
|
|
9
|
+
db.pragma('foreign_keys = ON');
|
|
10
|
+
initSchema(db);
|
|
11
|
+
return {
|
|
12
|
+
get(sql, params = []) {
|
|
13
|
+
return db.prepare(sql).get(...params);
|
|
14
|
+
},
|
|
15
|
+
all(sql, params = []) {
|
|
16
|
+
return db.prepare(sql).all(...params);
|
|
17
|
+
},
|
|
18
|
+
run(sql, params = []) {
|
|
19
|
+
db.prepare(sql).run(...params);
|
|
20
|
+
},
|
|
21
|
+
close() {
|
|
22
|
+
db.close();
|
|
23
|
+
},
|
|
24
|
+
get instance() {
|
|
25
|
+
return db;
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function initSchema(db) {
|
|
30
|
+
db.exec(`
|
|
31
|
+
CREATE TABLE IF NOT EXISTS pests (
|
|
32
|
+
id TEXT PRIMARY KEY,
|
|
33
|
+
name TEXT NOT NULL,
|
|
34
|
+
pest_type TEXT NOT NULL CHECK (pest_type IN ('insect', 'disease', 'weed')),
|
|
35
|
+
scientific_name TEXT,
|
|
36
|
+
crops_affected TEXT NOT NULL,
|
|
37
|
+
crop_category TEXT,
|
|
38
|
+
lifecycle TEXT,
|
|
39
|
+
identification TEXT,
|
|
40
|
+
damage_description TEXT,
|
|
41
|
+
language TEXT DEFAULT 'DE',
|
|
42
|
+
jurisdiction TEXT NOT NULL DEFAULT 'CH'
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
CREATE TABLE IF NOT EXISTS treatments (
|
|
46
|
+
id INTEGER PRIMARY KEY,
|
|
47
|
+
pest_id TEXT NOT NULL REFERENCES pests(id),
|
|
48
|
+
approach TEXT NOT NULL CHECK (approach IN ('chemical', 'biological', 'cultural', 'mechanical')),
|
|
49
|
+
product_name TEXT,
|
|
50
|
+
active_substance TEXT,
|
|
51
|
+
w_number TEXT,
|
|
52
|
+
dosage TEXT,
|
|
53
|
+
waiting_period TEXT,
|
|
54
|
+
timing TEXT,
|
|
55
|
+
restrictions TEXT,
|
|
56
|
+
pufferstreifen TEXT,
|
|
57
|
+
notes TEXT,
|
|
58
|
+
jurisdiction TEXT NOT NULL DEFAULT 'CH'
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
CREATE TABLE IF NOT EXISTS ipm_guidance (
|
|
62
|
+
id INTEGER PRIMARY KEY,
|
|
63
|
+
crop TEXT NOT NULL,
|
|
64
|
+
crop_category TEXT,
|
|
65
|
+
pest_id TEXT REFERENCES pests(id),
|
|
66
|
+
threshold TEXT,
|
|
67
|
+
monitoring_method TEXT,
|
|
68
|
+
cultural_controls TEXT,
|
|
69
|
+
prognose_system TEXT,
|
|
70
|
+
oeln_requirements TEXT,
|
|
71
|
+
notes TEXT,
|
|
72
|
+
jurisdiction TEXT NOT NULL DEFAULT 'CH'
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
CREATE TABLE IF NOT EXISTS approved_products (
|
|
76
|
+
id INTEGER PRIMARY KEY,
|
|
77
|
+
w_number TEXT NOT NULL,
|
|
78
|
+
product_name TEXT NOT NULL,
|
|
79
|
+
active_substance TEXT NOT NULL,
|
|
80
|
+
product_type TEXT,
|
|
81
|
+
crops TEXT,
|
|
82
|
+
target_organisms TEXT,
|
|
83
|
+
auflagen TEXT,
|
|
84
|
+
wartefrist TEXT,
|
|
85
|
+
dosage TEXT,
|
|
86
|
+
application_method TEXT,
|
|
87
|
+
spe3_buffer TEXT,
|
|
88
|
+
aktionsplan_status TEXT,
|
|
89
|
+
language TEXT DEFAULT 'DE',
|
|
90
|
+
jurisdiction TEXT NOT NULL DEFAULT 'CH'
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS search_index USING fts5(
|
|
94
|
+
title, body, pest_type, crop_category, jurisdiction
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
CREATE TABLE IF NOT EXISTS db_metadata (
|
|
98
|
+
key TEXT PRIMARY KEY,
|
|
99
|
+
value TEXT
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
INSERT OR IGNORE INTO db_metadata (key, value) VALUES ('schema_version', '1.0');
|
|
103
|
+
INSERT OR IGNORE INTO db_metadata (key, value) VALUES ('mcp_name', 'Switzerland Pest Management MCP');
|
|
104
|
+
INSERT OR IGNORE INTO db_metadata (key, value) VALUES ('jurisdiction', 'CH');
|
|
105
|
+
`);
|
|
106
|
+
}
|
|
107
|
+
const FTS_COLUMNS = ['title', 'body', 'pest_type', 'crop_category', 'jurisdiction'];
|
|
108
|
+
export function ftsSearch(db, query, limit = 20) {
|
|
109
|
+
const { results } = tieredFtsSearch(db, 'search_index', FTS_COLUMNS, query, limit);
|
|
110
|
+
return results;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Tiered FTS5 search with automatic fallback.
|
|
114
|
+
* Tiers: exact phrase -> AND -> prefix -> stemmed prefix -> OR -> LIKE
|
|
115
|
+
*/
|
|
116
|
+
export function tieredFtsSearch(db, table, columns, query, limit = 20) {
|
|
117
|
+
const sanitized = sanitizeFtsInput(query);
|
|
118
|
+
if (!sanitized.trim())
|
|
119
|
+
return { tier: 'empty', results: [] };
|
|
120
|
+
const columnList = columns.join(', ');
|
|
121
|
+
const select = `SELECT ${columnList}, rank FROM ${table}`;
|
|
122
|
+
const order = `ORDER BY rank LIMIT ?`;
|
|
123
|
+
// Tier 1: Exact phrase
|
|
124
|
+
const phrase = `"${sanitized}"`;
|
|
125
|
+
let results = tryFts(db, select, table, order, phrase, limit);
|
|
126
|
+
if (results.length > 0)
|
|
127
|
+
return { tier: 'phrase', results };
|
|
128
|
+
// Tier 2: AND
|
|
129
|
+
const words = sanitized.split(/\s+/).filter(w => w.length > 1);
|
|
130
|
+
if (words.length > 1) {
|
|
131
|
+
const andQuery = words.join(' AND ');
|
|
132
|
+
results = tryFts(db, select, table, order, andQuery, limit);
|
|
133
|
+
if (results.length > 0)
|
|
134
|
+
return { tier: 'and', results };
|
|
135
|
+
}
|
|
136
|
+
// Tier 3: Prefix
|
|
137
|
+
const prefixQuery = words.map(w => `${w}*`).join(' AND ');
|
|
138
|
+
results = tryFts(db, select, table, order, prefixQuery, limit);
|
|
139
|
+
if (results.length > 0)
|
|
140
|
+
return { tier: 'prefix', results };
|
|
141
|
+
// Tier 4: Stemmed prefix
|
|
142
|
+
const stemmed = words.map(w => stemWord(w) + '*');
|
|
143
|
+
const stemmedQuery = stemmed.join(' AND ');
|
|
144
|
+
if (stemmedQuery !== prefixQuery) {
|
|
145
|
+
results = tryFts(db, select, table, order, stemmedQuery, limit);
|
|
146
|
+
if (results.length > 0)
|
|
147
|
+
return { tier: 'stemmed', results };
|
|
148
|
+
}
|
|
149
|
+
// Tier 5: OR
|
|
150
|
+
if (words.length > 1) {
|
|
151
|
+
const orQuery = words.join(' OR ');
|
|
152
|
+
results = tryFts(db, select, table, order, orQuery, limit);
|
|
153
|
+
if (results.length > 0)
|
|
154
|
+
return { tier: 'or', results };
|
|
155
|
+
}
|
|
156
|
+
// Tier 6: LIKE fallback
|
|
157
|
+
const baseCols = ['name', 'pest_type'];
|
|
158
|
+
const likeConditions = words.map(() => `(${baseCols.map(c => `${c} LIKE ?`).join(' OR ')})`).join(' AND ');
|
|
159
|
+
const likeParams = words.flatMap(w => baseCols.map(() => `%${w}%`));
|
|
160
|
+
try {
|
|
161
|
+
const likeResults = db.all(`SELECT name as title, COALESCE(identification, '') as body, pest_type, COALESCE(crop_category, '') as crop_category, jurisdiction FROM pests WHERE ${likeConditions} LIMIT ?`, [...likeParams, limit]);
|
|
162
|
+
if (likeResults.length > 0)
|
|
163
|
+
return { tier: 'like', results: likeResults };
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
// LIKE fallback failed
|
|
167
|
+
}
|
|
168
|
+
return { tier: 'none', results: [] };
|
|
169
|
+
}
|
|
170
|
+
function tryFts(db, select, table, order, matchExpr, limit) {
|
|
171
|
+
try {
|
|
172
|
+
return db.all(`${select} WHERE ${table} MATCH ? ${order}`, [matchExpr, limit]);
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
return [];
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
function sanitizeFtsInput(query) {
|
|
179
|
+
return query
|
|
180
|
+
.replace(/["\u201C\u201D\u2018\u2019\u201A\u201E\u2039\u203A]/g, '"')
|
|
181
|
+
.replace(/[^a-zA-Z0-9\s*"_\u00C0-\u024F-]/g, ' ')
|
|
182
|
+
.replace(/\s+/g, ' ')
|
|
183
|
+
.trim();
|
|
184
|
+
}
|
|
185
|
+
function stemWord(word) {
|
|
186
|
+
return word
|
|
187
|
+
.replace(/(ung|heit|keit|lich|isch|ieren|tion|ment|ness|able|ible|ous|ive|ing|ers|ed|es|er|en|ly|s)$/i, '');
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=db.js.map
|
package/dist/db.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-server.d.ts","sourceRoot":"","sources":["../src/http-server.ts"],"names":[],"mappings":""}
|