county-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,35 @@
1
+ Metadata-Version: 2.4
2
+ Name: county-mcp
3
+ Version: 0.1.0
4
+ Summary: Kenya 47 counties local government data via MCP — budgets, services, CDF, wards. 6 tools. Thesis L9.
5
+ License: MIT
6
+ Requires-Python: >=3.10
7
+ Description-Content-Type: text/markdown
8
+ Requires-Dist: fastmcp>=0.9
9
+
10
+ # county-mcp
11
+
12
+ > Kenya 47-county local government data via MCP.
13
+
14
+ [![PyPI](https://img.shields.io/badge/PyPI-v0.1.0-blue?logo=pypi)](https://pypi.org/project/county-mcp/)
15
+ [![Thesis Layer](https://img.shields.io/badge/Thesis_Layer-L9_Civic_Infrastructure-orange)](https://gabrielmahia.github.io/nairobi-stack)
16
+
17
+ ## Install
18
+ ```bash
19
+ pip install county-mcp
20
+ ```
21
+
22
+ ## Tools (6) — All 47 counties covered
23
+ | Tool | Description |
24
+ |------|-------------|
25
+ | `county_information` | Demographics, area, wards, constituencies for all 47 counties |
26
+ | `county_budget_guide` | Devolution funding, equitable share, own-source revenue |
27
+ | `county_services_guide` | What services are provided at county vs national level |
28
+ | `cdf_guide` | Constituency Development Fund — bursaries, project proposals |
29
+ | `ward_information` | MCA role, ward development fund, how to petition county assembly |
30
+ | `county_contact_directory` | County government websites, governor offices, assembly contacts |
31
+
32
+ → [The Nairobi Stack](https://gabrielmahia.github.io/nairobi-stack)
33
+
34
+ ## License
35
+ MIT © Gabriel Mahia | contact@aikungfu.dev
@@ -0,0 +1,26 @@
1
+ # county-mcp
2
+
3
+ > Kenya 47-county local government data via MCP.
4
+
5
+ [![PyPI](https://img.shields.io/badge/PyPI-v0.1.0-blue?logo=pypi)](https://pypi.org/project/county-mcp/)
6
+ [![Thesis Layer](https://img.shields.io/badge/Thesis_Layer-L9_Civic_Infrastructure-orange)](https://gabrielmahia.github.io/nairobi-stack)
7
+
8
+ ## Install
9
+ ```bash
10
+ pip install county-mcp
11
+ ```
12
+
13
+ ## Tools (6) — All 47 counties covered
14
+ | Tool | Description |
15
+ |------|-------------|
16
+ | `county_information` | Demographics, area, wards, constituencies for all 47 counties |
17
+ | `county_budget_guide` | Devolution funding, equitable share, own-source revenue |
18
+ | `county_services_guide` | What services are provided at county vs national level |
19
+ | `cdf_guide` | Constituency Development Fund — bursaries, project proposals |
20
+ | `ward_information` | MCA role, ward development fund, how to petition county assembly |
21
+ | `county_contact_directory` | County government websites, governor offices, assembly contacts |
22
+
23
+ → [The Nairobi Stack](https://gabrielmahia.github.io/nairobi-stack)
24
+
25
+ ## License
26
+ MIT © Gabriel Mahia | contact@aikungfu.dev
@@ -0,0 +1,18 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "county-mcp"
7
+ version = "0.1.0"
8
+ description = "Kenya 47 counties local government data via MCP — budgets, services, CDF, wards. 6 tools. Thesis L9."
9
+ readme = "README.md"
10
+ license = { text = "MIT" }
11
+ requires-python = ">=3.10"
12
+ dependencies = ["fastmcp>=0.9"]
13
+
14
+ [project.scripts]
15
+ county-mcp = "county_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
+ """county-mcp v0.1.0"""
2
+ __version__ = "0.1.0"
@@ -0,0 +1,172 @@
1
+ """CountyMCP — Kenya 47 Counties Local Government Data (6 tools). All data DEMO."""
2
+ from __future__ import annotations
3
+ from typing import Optional
4
+ from fastmcp import FastMCP
5
+ mcp = FastMCP(name="county-mcp", description="Kenya 47 counties local government data. DEMO.")
6
+
7
+ COUNTIES = {
8
+ "Nairobi": {"code": 47, "pop": 4397073, "area_km2": 695.1, "region": "Nairobi", "wards": 85, "constituencies": 17},
9
+ "Mombasa": {"code": 1, "pop": 1208333, "area_km2": 229.9, "region": "Coast", "wards": 30, "constituencies": 6},
10
+ "Kwale": {"code": 2, "pop": 866820, "area_km2": 8270.3, "region": "Coast", "wards": 20, "constituencies": 4},
11
+ "Kilifi": {"code": 3, "pop": 1453787, "area_km2": 12245.9, "region": "Coast", "wards": 35, "constituencies": 7},
12
+ "Tana River": {"code": 4, "pop": 315943, "area_km2": 35375.8, "region": "Coast", "wards": 15, "constituencies": 3},
13
+ "Lamu": {"code": 5, "pop": 143920, "area_km2": 6497.7, "region": "Coast", "wards": 10, "constituencies": 2},
14
+ "Taita-Taveta": {"code": 6, "pop": 340671, "area_km2": 17083.9, "region": "Coast", "wards": 20, "constituencies": 4},
15
+ "Garissa": {"code": 7, "pop": 841353, "area_km2": 44175.9, "region": "North Eastern", "wards": 20, "constituencies": 6},
16
+ "Wajir": {"code": 8, "pop": 661941, "area_km2": 56685.8, "region": "North Eastern", "wards": 25, "constituencies": 6},
17
+ "Mandera": {"code": 9, "pop": 867457, "area_km2": 25797.3, "region": "North Eastern", "wards": 30, "constituencies": 6},
18
+ "Marsabit": {"code": 10, "pop": 459785, "area_km2": 70961.2, "region": "Eastern", "wards": 20, "constituencies": 4},
19
+ "Isiolo": {"code": 11, "pop": 268002, "area_km2": 25336.1, "region": "Eastern", "wards": 9, "constituencies": 2},
20
+ "Meru": {"code": 12, "pop": 1545714, "area_km2": 6936.2, "region": "Eastern", "wards": 45, "constituencies": 9},
21
+ "Tharaka-Nithi": {"code": 13, "pop": 393177, "area_km2": 2609.4, "region": "Eastern", "wards": 15, "constituencies": 3},
22
+ "Embu": {"code": 14, "pop": 608599, "area_km2": 2818.2, "region": "Eastern", "wards": 25, "constituencies": 4},
23
+ "Kitui": {"code": 15, "pop": 1136187, "area_km2": 24385.1, "region": "Eastern", "wards": 40, "constituencies": 8},
24
+ "Machakos": {"code": 16, "pop": 1421932, "area_km2": 6208.2, "region": "Eastern", "wards": 40, "constituencies": 8},
25
+ "Makueni": {"code": 17, "pop": 987653, "area_km2": 8008.9, "region": "Eastern", "wards": 30, "constituencies": 6},
26
+ "Nyandarua": {"code": 18, "pop": 638289, "area_km2": 3304.7, "region": "Central", "wards": 25, "constituencies": 5},
27
+ "Nyeri": {"code": 19, "pop": 759164, "area_km2": 3337.1, "region": "Central", "wards": 35, "constituencies": 7},
28
+ "Kirinyaga": {"code": 20, "pop": 610411, "area_km2": 1478.1, "region": "Central", "wards": 20, "constituencies": 5},
29
+ "Muranga": {"code": 21, "pop": 1056640, "area_km2": 2558.8, "region": "Central", "wards": 30, "constituencies": 7},
30
+ "Kiambu": {"code": 22, "pop": 2417735, "area_km2": 2543.5, "region": "Central", "wards": 60, "constituencies": 12},
31
+ "Turkana": {"code": 23, "pop": 926976, "area_km2": 77000.0, "region": "Rift Valley", "wards": 45, "constituencies": 6},
32
+ "West Pokot": {"code": 24, "pop": 512690, "area_km2": 9169.4, "region": "Rift Valley", "wards": 20, "constituencies": 4},
33
+ "Samburu": {"code": 25, "pop": 310327, "area_km2": 20182.5, "region": "Rift Valley", "wards": 15, "constituencies": 3},
34
+ "Trans Nzoia": {"code": 26, "pop": 990341, "area_km2": 2495.5, "region": "Rift Valley", "wards": 25, "constituencies": 5},
35
+ "Uasin Gishu": {"code": 27, "pop": 1163186, "area_km2": 3345.2, "region": "Rift Valley", "wards": 30, "constituencies": 6},
36
+ "Elgeyo-Marakwet": {"code": 28, "pop": 454480, "area_km2": 3030.4, "region": "Rift Valley", "wards": 20, "constituencies": 4},
37
+ "Nandi": {"code": 29, "pop": 885711, "area_km2": 2884.5, "region": "Rift Valley", "wards": 25, "constituencies": 6},
38
+ "Baringo": {"code": 30, "pop": 666763, "area_km2": 11075.3, "region": "Rift Valley", "wards": 30, "constituencies": 6},
39
+ "Laikipia": {"code": 31, "pop": 518560, "area_km2": 9462.5, "region": "Rift Valley", "wards": 25, "constituencies": 3},
40
+ "Nakuru": {"code": 32, "pop": 2162202, "area_km2": 7495.1, "region": "Rift Valley", "wards": 55, "constituencies": 11},
41
+ "Narok": {"code": 33, "pop": 1157873, "area_km2": 17933.1, "region": "Rift Valley", "wards": 30, "constituencies": 6},
42
+ "Kajiado": {"code": 34, "pop": 1117840, "area_km2": 21901.1, "region": "Rift Valley", "wards": 25, "constituencies": 5},
43
+ "Kericho": {"code": 35, "pop": 901777, "area_km2": 2454.5, "region": "Rift Valley", "wards": 30, "constituencies": 6},
44
+ "Bomet": {"code": 36, "pop": 857823, "area_km2": 1997.1, "region": "Rift Valley", "wards": 25, "constituencies": 5},
45
+ "Kakamega": {"code": 37, "pop": 1867579, "area_km2": 3033.8, "region": "Western", "wards": 60, "constituencies": 12},
46
+ "Vihiga": {"code": 38, "pop": 590013, "area_km2": 563.3, "region": "Western", "wards": 25, "constituencies": 5},
47
+ "Bungoma": {"code": 39, "pop": 1670570, "area_km2": 3032.2, "region": "Western", "wards": 45, "constituencies": 9},
48
+ "Busia": {"code": 40, "pop": 893681, "area_km2": 1695.4, "region": "Western", "wards": 35, "constituencies": 7},
49
+ "Siaya": {"code": 41, "pop": 993183, "area_km2": 2530.5, "region": "Nyanza", "wards": 30, "constituencies": 6},
50
+ "Kisumu": {"code": 42, "pop": 1155574, "area_km2": 2085.9, "region": "Nyanza", "wards": 35, "constituencies": 7},
51
+ "Homa Bay": {"code": 43, "pop": 1131950, "area_km2": 3154.7, "region": "Nyanza", "wards": 40, "constituencies": 8},
52
+ "Migori": {"code": 44, "pop": 1116436, "area_km2": 2586.4, "region": "Nyanza", "wards": 35, "constituencies": 8},
53
+ "Kisii": {"code": 45, "pop": 1266860, "area_km2": 1317.6, "region": "Nyanza", "wards": 45, "constituencies": 9},
54
+ "Nyamira": {"code": 46, "pop": 605576, "area_km2": 899.3, "region": "Nyanza", "wards": 25, "constituencies": 4},
55
+ }
56
+
57
+ @mcp.tool(name="county_information", description="Kenya county demographics and basic statistics. DEMO.")
58
+ def county_information(county: Optional[str] = None, region: Optional[str] = None) -> dict:
59
+ if county:
60
+ c = county.title()
61
+ info = COUNTIES.get(c)
62
+ if info:
63
+ return {"source": "DEMO — KNBS 2019 Census", "county": c, **info,
64
+ "county_code": info["code"],
65
+ "government": f"county.go.ke (each county has a website at [county].go.ke)"}
66
+ return {"error": f"County '{county}' not found", "available": list(COUNTIES.keys())}
67
+ if region:
68
+ counties = {k: v for k, v in COUNTIES.items() if v["region"].lower() == region.lower()}
69
+ return {"source": "DEMO", "region": region, "counties": counties, "count": len(counties)}
70
+ return {"source": "DEMO — KNBS 2019 Census", "all_counties": {k: {"code": v["code"], "pop": v["pop"], "region": v["region"]} for k, v in COUNTIES.items()},
71
+ "total": 47, "regions": list(set(v["region"] for v in COUNTIES.values()))}
72
+
73
+ @mcp.tool(name="county_budget_guide", description="Kenya county devolution and budget information. DEMO.")
74
+ def county_budget_guide(county: Optional[str] = None) -> dict:
75
+ # Rough equitable share allocations (DEMO - based on 2024/25 estimates)
76
+ BUDGETS = {
77
+ "Nairobi": 17800, "Nakuru": 8200, "Kiambu": 8100, "Kakamega": 7900, "Meru": 7100,
78
+ "Turkana": 9800, "Marsabit": 8500, "Garissa": 8100, "Wajir": 7900, "Mandera": 8600,
79
+ }
80
+ if county:
81
+ c = county.title()
82
+ budget = BUDGETS.get(c, 5000) # default estimate
83
+ return {"source": "DEMO — Controller of Budget Kenya", "county": c,
84
+ "equitable_share_kes_million": budget,
85
+ "own_source_revenue": "Counties collect property rates, business permits, market fees, etc.",
86
+ "devolved_functions": ["Health services", "Pre-primary education", "County roads", "Agriculture", "Trade"],
87
+ "budget_documents": "Each county publishes Annual Development Plan and Budget at county.go.ke",
88
+ "controller_of_budget": "cob.go.ke — oversees all county budgets",
89
+ "disclaimer": "DEMO figures. Actual allocations from National Treasury vary annually."}
90
+ return {"source": "DEMO — Controller of Budget Kenya",
91
+ "how_counties_funded": {
92
+ "equitable_share": "At least 15% of national revenue shared by formula (population, land area, poverty, fiscal responsibility)",
93
+ "own_source": "Counties collect local revenue (permits, rates, fees)",
94
+ "conditional_grants": "National government grants for specific programs",
95
+ },
96
+ "oversight": "Controller of Budget (cob.go.ke) + County Assembly",
97
+ "total_devolution_budget_2025": "~KES 400 billion across 47 counties",
98
+ "cdf": "CDF (Constituency Development Fund) is separate from county — managed by MPs. cdf.go.ke"}
99
+
100
+ @mcp.tool(name="county_services_guide", description="Services available at Kenya county government level. DEMO.")
101
+ def county_services_guide(service: Optional[str] = None) -> dict:
102
+ SERVICES = {
103
+ "health": "Primary health facilities (dispensaries, health centres), referral system to national hospitals",
104
+ "water": "Rural water supply, borehole maintenance (county and national shared mandate)",
105
+ "roads": "County roads maintenance (national roads by Kenya Roads Authority)",
106
+ "markets": "Market infrastructure, market fees collection",
107
+ "permits": "Business permits, building permits, health certificates",
108
+ "agriculture": "Agricultural extension services, county demonstration farms",
109
+ "education": "Pre-primary (ECDE) schools and ECD teachers",
110
+ "environment": "Solid waste management, local environmental regulations",
111
+ "trade": "County trade facilitation, hawker licensing",
112
+ "id_services": "National ID is a national government function. Physical address can be done at sub-county offices.",
113
+ }
114
+ if service:
115
+ s = service.lower()
116
+ matched = {k: v for k, v in SERVICES.items() if k in s or s in k or s in v.lower()}
117
+ return {"source": "DEMO — County Governments Act 2012", "service": service, "info": matched or SERVICES}
118
+ return {"source": "DEMO — County Governments Act 2012", "devolved_services": SERVICES,
119
+ "national_services": "National ID, passport, KRA, land titles — national government",
120
+ "contact": "Visit your sub-county office. Directory at county.go.ke"}
121
+
122
+ @mcp.tool(name="cdf_guide", description="Kenya Constituency Development Fund (CDF) guide. DEMO.")
123
+ def cdf_guide() -> dict:
124
+ return {"source": "DEMO — CDF Act 2013 (Kenya)", "what_is_cdf":
125
+ "Constituency Development Fund allocates 2.5% of national revenue to 290 constituencies for development projects.",
126
+ "how_it_works": {
127
+ "amount": "Each constituency gets KES 100-200M+ annually (varies by allocation formula)",
128
+ "managed_by": "Constituency Development Fund Committee, chaired by area MP",
129
+ "funded_projects": ["Bursaries (primary education focus)", "Classroom construction", "Health centres", "Water projects", "Roads", "Sports facilities"],
130
+ "bursary": "CDF bursaries for needy students. Apply at constituency office during school term. Usually KES 5,000–20,000 per student.",
131
+ },
132
+ "how_to_access": {
133
+ "bursary": "Collect form from MP's office or constituency office. Provide: admission letter, fee statement, ID (guardian). Apply before deadlines.",
134
+ "project_proposal": "Submit community project proposals to CDF committee in your constituency",
135
+ "contact": "cdf.go.ke | Your area MP's office",
136
+ },
137
+ "accountability": "CDF accounts must be audited. Misuse is a criminal offence under the CDF Act.",
138
+ "portal": "cdf.go.ke"}
139
+
140
+ @mcp.tool(name="ward_information", description="Kenya ward-level civic information and ward representative role. DEMO.")
141
+ def ward_information(county: Optional[str] = None) -> dict:
142
+ return {"source": "DEMO — IEBC Kenya", "what_is_ward":
143
+ "Kenya is divided into 1,450 wards (sub-units of constituencies). Each ward elects a Member of County Assembly (MCA).",
144
+ "mca_role": {
145
+ "legislative": "Passes county legislation. Approves county budget.",
146
+ "oversight": "Oversees county governor and executive.",
147
+ "ward_development": "Ward Development Fund — small development budget for projects in the ward.",
148
+ "bursary": "Some MCAs have ward bursary funds similar to CDF. Inquire at ward office.",
149
+ },
150
+ "ward_development_fund": "Each MCA ward gets KES 5-10M annually for development projects.",
151
+ "how_to_reach_mca": "Visit your ward office. MCA contact via county assembly website or IEBC portal.",
152
+ "county_assembly": f"County assembly for {county or 'any county'} handles legislation and petitions. Visit county.go.ke",
153
+ "petition_mca": "Citizens can petition the county assembly on any matter affecting their county.",
154
+ "iebc": "iebc.or.ke — find your ward, constituency, and county representatives"}
155
+
156
+ @mcp.tool(name="county_contact_directory", description="Kenya county government contact directory. DEMO.")
157
+ def county_contact_directory(county: Optional[str] = None) -> dict:
158
+ CONTACTS = {
159
+ "Nairobi": {"website": "nairobi.go.ke", "governor_office": "0800720007", "county_assembly": "nairobica.go.ke"},
160
+ "Mombasa": {"website": "mombasa.go.ke", "governor_office": "041-2492022", "county_assembly": "mombasacountyassembly.go.ke"},
161
+ "Kisumu": {"website": "kisumu.go.ke", "governor_office": "057-2022000", "county_assembly": "kisumucountyassembly.go.ke"},
162
+ "Nakuru": {"website": "nakuru.go.ke", "governor_office": "051-2212888", "county_assembly": "nakuruca.go.ke"},
163
+ "Kiambu": {"website": "kiambu.go.ke", "governor_office": "0725-000100", "county_assembly": "kiambu.go.ke/county-assembly"},
164
+ }
165
+ if county:
166
+ c = county.title()
167
+ info = CONTACTS.get(c, {"website": f"{c.lower().replace(' ','')}.go.ke", "note": "All 47 counties have websites at [countyname].go.ke"})
168
+ return {"source": "DEMO", "county": c, "contact": info}
169
+ return {"source": "DEMO", "contacts": CONTACTS,
170
+ "general_pattern": "All counties: [countyname].go.ke (e.g. nakuru.go.ke, kisumu.go.ke)",
171
+ "county_assembly_pattern": "[countyname]ca.go.ke or [countyname].go.ke/county-assembly",
172
+ "all_contacts": "kenya.go.ke/counties | 47counties.go.ke"}
@@ -0,0 +1,35 @@
1
+ Metadata-Version: 2.4
2
+ Name: county-mcp
3
+ Version: 0.1.0
4
+ Summary: Kenya 47 counties local government data via MCP — budgets, services, CDF, wards. 6 tools. Thesis L9.
5
+ License: MIT
6
+ Requires-Python: >=3.10
7
+ Description-Content-Type: text/markdown
8
+ Requires-Dist: fastmcp>=0.9
9
+
10
+ # county-mcp
11
+
12
+ > Kenya 47-county local government data via MCP.
13
+
14
+ [![PyPI](https://img.shields.io/badge/PyPI-v0.1.0-blue?logo=pypi)](https://pypi.org/project/county-mcp/)
15
+ [![Thesis Layer](https://img.shields.io/badge/Thesis_Layer-L9_Civic_Infrastructure-orange)](https://gabrielmahia.github.io/nairobi-stack)
16
+
17
+ ## Install
18
+ ```bash
19
+ pip install county-mcp
20
+ ```
21
+
22
+ ## Tools (6) — All 47 counties covered
23
+ | Tool | Description |
24
+ |------|-------------|
25
+ | `county_information` | Demographics, area, wards, constituencies for all 47 counties |
26
+ | `county_budget_guide` | Devolution funding, equitable share, own-source revenue |
27
+ | `county_services_guide` | What services are provided at county vs national level |
28
+ | `cdf_guide` | Constituency Development Fund — bursaries, project proposals |
29
+ | `ward_information` | MCA role, ward development fund, how to petition county assembly |
30
+ | `county_contact_directory` | County government websites, governor offices, assembly contacts |
31
+
32
+ → [The Nairobi Stack](https://gabrielmahia.github.io/nairobi-stack)
33
+
34
+ ## License
35
+ MIT © Gabriel Mahia | contact@aikungfu.dev
@@ -0,0 +1,10 @@
1
+ README.md
2
+ pyproject.toml
3
+ src/county_mcp/__init__.py
4
+ src/county_mcp/server.py
5
+ src/county_mcp.egg-info/PKG-INFO
6
+ src/county_mcp.egg-info/SOURCES.txt
7
+ src/county_mcp.egg-info/dependency_links.txt
8
+ src/county_mcp.egg-info/entry_points.txt
9
+ src/county_mcp.egg-info/requires.txt
10
+ src/county_mcp.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ county-mcp = county_mcp.server:mcp.run
@@ -0,0 +1 @@
1
+ fastmcp>=0.9
@@ -0,0 +1 @@
1
+ county_mcp