kilimo-mcp 0.1.0__tar.gz

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.
@@ -0,0 +1,11 @@
1
+ Metadata-Version: 2.4
2
+ Name: kilimo-mcp
3
+ Version: 0.1.0
4
+ Summary: MCP server for Kenya precision agriculture — crop calendar, fertilizer guide, pe
5
+ License: MIT
6
+ Requires-Python: >=3.10
7
+ Description-Content-Type: text/markdown
8
+ Requires-Dist: fastmcp>=0.9
9
+
10
+ # kilimo-mcp
11
+ MCP server for Kenya precision agriculture — crop calendar, fertilizer guide, pest alerts, market timing, KALRO varieties, input cost calculator. 6 tools. 1st world equivalent: Climate Corp / Granular.
@@ -0,0 +1,2 @@
1
+ # kilimo-mcp
2
+ MCP server for Kenya precision agriculture — crop calendar, fertilizer guide, pest alerts, market timing, KALRO varieties, input cost calculator. 6 tools. 1st world equivalent: Climate Corp / Granular.
@@ -0,0 +1,18 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "kilimo-mcp"
7
+ version = "0.1.0"
8
+ description = "MCP server for Kenya precision agriculture — crop calendar, fertilizer guide, pe"
9
+ readme = "README.md"
10
+ license = { text = "MIT" }
11
+ requires-python = ">=3.10"
12
+ dependencies = ["fastmcp>=0.9"]
13
+
14
+ [project.scripts]
15
+ kilimo-mcp = "kilimo_mcp.server:mcp.run"
16
+
17
+ [tool.setuptools.packages.find]
18
+ where = ["src"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,2 @@
1
+ """MCP server for kilimo-mcp."""
2
+ __version__ = "0.1.0"
@@ -0,0 +1,132 @@
1
+ """KilimoMCP — Kenya Precision Agriculture Tools (6 tools). All data DEMO."""
2
+ from __future__ import annotations
3
+ from typing import Optional
4
+ from fastmcp import FastMCP
5
+ mcp = FastMCP(name="kilimo-mcp", description="Kenya precision agriculture tools. DEMO data only.")
6
+
7
+ CALENDARS = {
8
+ "maize": {
9
+ "highland": {"plant": "Mar-Apr (long rains), Oct-Nov (short rains)", "harvest": "Jul-Aug, Feb-Mar", "days_to_maturity": "90-120"},
10
+ "lowland": {"plant": "Mar-Apr", "harvest": "Jul-Aug", "days_to_maturity": "80-90"},
11
+ },
12
+ "beans": {"highland": {"plant": "Mar-Apr, Oct-Nov", "harvest": "Jun-Jul, Jan-Feb", "days_to_maturity": "60-90"}},
13
+ "tea": {"highland": {"plant": "Any season (perennial)", "harvest": "Year-round (peak Apr-Jun, Oct-Dec)", "days_to_maturity": "3 years to full production"}},
14
+ "coffee": {"highland": {"plant": "Apr-Jun", "harvest": "Oct-Jan (main), Mar-May (fly)", "days_to_maturity": "3-4 years to production"}},
15
+ "potato": {"highland": {"plant": "Mar-Apr, Sep-Oct", "harvest": "Jun-Jul, Jan-Feb", "days_to_maturity": "90-100"}},
16
+ "tomato": {"highland": {"plant": "Any season with irrigation", "harvest": "60-80 days after transplant", "days_to_maturity": "60-80"}},
17
+ "sukuma_wiki": {"all": {"plant": "Any season", "harvest": "6 weeks after planting (continuous)", "days_to_maturity": "42"}},
18
+ }
19
+
20
+ @mcp.tool(name="crop_calendar", description="Kenya crop planting and harvesting calendar by region. DEMO.")
21
+ def crop_calendar(crop: str, region: Optional[str] = "highland") -> dict:
22
+ c = crop.lower().replace(" ","_")
23
+ data = CALENDARS.get(c, {})
24
+ r_data = data.get(region.lower() if region else "highland") or data.get("all") or {"note": "Crop not in sample dataset"}
25
+ return {"source": "DEMO — KALRO and Ministry of Agriculture", "crop": crop, "region": region,
26
+ **r_data, "long_rains": "March–May (main planting)", "short_rains": "October–December",
27
+ "kalro": "kalro.org for official crop recommendations"}
28
+
29
+ @mcp.tool(name="fertilizer_guide", description="Fertilizer recommendations by Kenya crop and soil type. DEMO.")
30
+ def fertilizer_guide(crop: str, soil_type: Optional[str] = "medium") -> dict:
31
+ GUIDE = {
32
+ "maize": {"basal": "DAP 50kg/acre at planting", "top_dress": "CAN 50kg/acre 6 weeks after planting",
33
+ "organic": "2–3 tons/acre well-composted manure before planting"},
34
+ "beans": {"basal": "DAP 25kg/acre (beans fix nitrogen)", "top_dress": "None usually needed",
35
+ "organic": "Compost improves yield significantly"},
36
+ "tomato": {"basal": "NPK 17:17:17 at 50kg/acre", "top_dress": "CAN 25kg/acre weekly foliar",
37
+ "organic": "Heavy manure user — 5 tons/acre recommended"},
38
+ "potato": {"basal": "DSP or NPK 23:23:0 at 200kg/acre", "top_dress": "CAN 50kg/acre at 6 weeks",
39
+ "organic": "Potato responds well to manure + inorganic combo"},
40
+ }
41
+ c = crop.lower()
42
+ rec = GUIDE.get(c, {"general": "Apply DAP at planting, CAN at 6 weeks. Get soil test from KARI/KALRO lab."})
43
+ return {"source": "DEMO — KALRO Fertilizer Use Recommendations", "crop": crop, "soil_type": soil_type,
44
+ **rec, "soil_test": "Get soil test at KALRO soil lab: kalro.org (costs ~KES 1,000/sample)",
45
+ "subsidy": "Kenya fertilizer subsidy scheme: check county agriculture office"}
46
+
47
+ @mcp.tool(name="pest_disease_alert", description="Kenya crop pest and disease management guide. DEMO.")
48
+ def pest_disease_alert(crop: str, symptom: Optional[str] = None) -> dict:
49
+ PESTS = {
50
+ "maize": [{"name": "Fall Armyworm", "symptom": "Ragged holes in leaves, frass in whorls",
51
+ "management": "Emamectin benzoate or chlorpyrifos. Early morning application. Report to county pest control."},
52
+ {"name": "Maize Lethal Necrosis", "symptom": "Yellow streaking, premature drying",
53
+ "management": "No cure. Remove and destroy affected plants. Use certified seed."}],
54
+ "tomato": [{"name": "Late Blight", "symptom": "Brown lesions on leaves and fruit",
55
+ "management": "Mancozeb or metalaxyl fungicide. Remove affected leaves."},
56
+ {"name": "Tuta absoluta", "symptom": "Mines in leaves, bored fruit",
57
+ "management": "Pheromone traps, spinosad, cyantraniliprole"}],
58
+ "beans": [{"name": "Bean fly", "symptom": "Yellowing, wilting seedlings",
59
+ "management": "Seed treatment with thiamethoxam. Early planting."},
60
+ {"name": "Angular leaf spot", "symptom": "Brown angular lesions",
61
+ "management": "Copper-based fungicide. Use resistant varieties."}],
62
+ }
63
+ c = crop.lower()
64
+ pests = PESTS.get(c, [{"name": "General", "symptom": "Multiple", "management": "Consult county extension officer"}])
65
+ if symptom:
66
+ pests = [p for p in pests if symptom.lower() in p["symptom"].lower()] or pests
67
+ return {"source": "DEMO — KEPHIS and county extension services", "crop": crop,
68
+ "common_pests_diseases": pests, "emergency": "Pest outbreak: call KEPHIS 020-3597481",
69
+ "fall_armyworm_hotline": "0800720553 (Kenya FAO FAW reporting)"}
70
+
71
+ @mcp.tool(name="market_timing_guide", description="Best timing to sell Kenya produce based on price cycles. DEMO.")
72
+ def market_timing_guide(commodity: str, county: Optional[str] = None) -> dict:
73
+ TIMING = {
74
+ "maize": {"best_sell_months": ["Aug","Sep","Oct","Feb","Mar"],
75
+ "low_price_months": ["May","Jun"] ,
76
+ "tip": "Store 2-3 months after harvest to capture price recovery. Avoid selling in Jun-Jul (harvest glut)."},
77
+ "tomatoes": {"best_sell_months": ["Jan","Feb","Jul","Aug"],
78
+ "low_price_months": ["Apr","May","Oct","Nov"],
79
+ "tip": "Seasonal gluts in Apr-May (long rains) and Oct-Nov (short rains). Consider processing to paste."},
80
+ "beans": {"best_sell_months": ["Sep","Oct","Mar","Apr"],
81
+ "low_price_months": ["Jul","Aug","Jan"],
82
+ "tip": "Dry beans store well — hold 1-2 months after harvest for 20-40% price premium."},
83
+ }
84
+ c = commodity.lower()
85
+ timing = TIMING.get(c, {"tip": "Monitor WFP Kenya market prices at vam.wfp.org"})
86
+ return {"source": "DEMO — WFP VAM Kenya Market Monitor", "commodity": commodity, "county": county,
87
+ **timing, "real_time_prices": "vam.wfp.org | soko-mcp for current market prices"}
88
+
89
+ @mcp.tool(name="kalro_varieties", description="KALRO improved crop variety recommendations for Kenya. DEMO.")
90
+ def kalro_varieties(crop: str, condition: Optional[str] = None) -> dict:
91
+ VARIETIES = {
92
+ "maize": [
93
+ {"variety": "H614D", "days": 120, "condition": "highland, 1500-2100m", "yield": "30-40 bags/acre"},
94
+ {"variety": "DK8031", "days": 90, "condition": "lowland, drought-tolerant", "yield": "20-30 bags/acre"},
95
+ {"variety": "WEMA (drought-tolerant)", "days": 85, "condition": "ASAL, drought stress", "yield": "15-25 bags/acre"},
96
+ ],
97
+ "beans": [
98
+ {"variety": "Fahari", "days": 65, "condition": "highland, root rot resistant", "yield": "600-800kg/acre"},
99
+ {"variety": "Lyamungu 85", "days": 75, "condition": "medium altitude", "yield": "500-700kg/acre"},
100
+ ],
101
+ "potato": [
102
+ {"variety": "Dutch Robjin", "days": 90, "condition": "highland, all-purpose", "yield": "8-12 tons/acre"},
103
+ {"variety": "Shangi", "days": 90, "condition": "highland, late blight resistant", "yield": "10-15 tons/acre"},
104
+ ],
105
+ }
106
+ c = crop.lower()
107
+ varieties = VARIETIES.get(c, [{"note": f"Varieties for {crop} not in sample dataset — visit kalro.org"}])
108
+ if condition:
109
+ filtered = [v for v in varieties if condition.lower() in v.get("condition","").lower()]
110
+ varieties = filtered or varieties
111
+ return {"source": "DEMO — KALRO Kenya", "crop": crop, "condition": condition,
112
+ "recommended_varieties": varieties, "certified_seed": "Obtain from KEPHIS-registered agrodealers",
113
+ "kalro": "kalro.org | 0722206986"}
114
+
115
+ @mcp.tool(name="input_cost_calculator", description="Kenya farm input cost calculator and comparison. DEMO.")
116
+ def input_cost_calculator(crop: str, acreage: float = 1.0) -> dict:
117
+ COSTS = {
118
+ "maize": {"seed_kg": 10, "seed_cost": 600, "dap_kg": 50, "dap_cost": 5500,
119
+ "can_kg": 50, "can_cost": 4500, "labour_kes": 8000, "other_kes": 2000},
120
+ "tomato": {"seedlings": 2000, "seedling_cost": 4000, "fertilizer_kes": 12000,
121
+ "pesticides_kes": 8000, "irrigation_kes": 5000, "labour_kes": 15000},
122
+ "beans": {"seed_kg": 20, "seed_cost": 3000, "dap_kg": 25, "dap_cost": 2750,
123
+ "pesticide_kes": 2000, "labour_kes": 5000},
124
+ }
125
+ c = crop.lower()
126
+ base = COSTS.get(c, {"note": "Crop not in sample — estimate KES 30,000-80,000/acre for most crops"})
127
+ total = sum(v for k, v in base.items() if k.endswith("_kes") or k.endswith("_cost"))
128
+ total_scaled = round(total * acreage, 0)
129
+ return {"source": "DEMO — Kenya agrovet prices indicative 2025", "crop": crop, "acreage": acreage,
130
+ "input_costs_per_acre_kes": base, "estimated_total_kes": total_scaled,
131
+ "subsidy": "Fertilizer subsidy may reduce DAP/CAN costs — check county agriculture office",
132
+ "disclaimer": "Prices vary by region and season. Get current quotes from your local agrodealer."}
@@ -0,0 +1,11 @@
1
+ Metadata-Version: 2.4
2
+ Name: kilimo-mcp
3
+ Version: 0.1.0
4
+ Summary: MCP server for Kenya precision agriculture — crop calendar, fertilizer guide, pe
5
+ License: MIT
6
+ Requires-Python: >=3.10
7
+ Description-Content-Type: text/markdown
8
+ Requires-Dist: fastmcp>=0.9
9
+
10
+ # kilimo-mcp
11
+ MCP server for Kenya precision agriculture — crop calendar, fertilizer guide, pest alerts, market timing, KALRO varieties, input cost calculator. 6 tools. 1st world equivalent: Climate Corp / Granular.
@@ -0,0 +1,10 @@
1
+ README.md
2
+ pyproject.toml
3
+ src/kilimo_mcp/__init__.py
4
+ src/kilimo_mcp/server.py
5
+ src/kilimo_mcp.egg-info/PKG-INFO
6
+ src/kilimo_mcp.egg-info/SOURCES.txt
7
+ src/kilimo_mcp.egg-info/dependency_links.txt
8
+ src/kilimo_mcp.egg-info/entry_points.txt
9
+ src/kilimo_mcp.egg-info/requires.txt
10
+ src/kilimo_mcp.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ kilimo-mcp = kilimo_mcp.server:mcp.run
@@ -0,0 +1 @@
1
+ fastmcp>=0.9
@@ -0,0 +1 @@
1
+ kilimo_mcp