<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Gabriel Mahia</title>
    <description>The latest articles on DEV Community by Gabriel Mahia (@gabrielmahia).</description>
    <link>https://dev.to/gabrielmahia</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3816762%2Fa0204949-e28c-4d88-862d-f8723ceddf03.jpeg</url>
      <title>DEV Community: Gabriel Mahia</title>
      <link>https://dev.to/gabrielmahia</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gabrielmahia"/>
    <language>en</language>
    <item>
      <title>The Agricultural Data Africa Needs Already Exists. It's Just 100 Years Old.</title>
      <dc:creator>Gabriel Mahia</dc:creator>
      <pubDate>Tue, 11 Aug 2026 10:00:00 +0000</pubDate>
      <link>https://dev.to/gabrielmahia/the-agricultural-data-africa-needs-already-exists-its-just-100-years-old-1l1f</link>
      <guid>https://dev.to/gabrielmahia/the-agricultural-data-africa-needs-already-exists-its-just-100-years-old-1l1f</guid>
      <description>&lt;p&gt;The data problem for AI in African agriculture is not a lack of data.&lt;/p&gt;

&lt;p&gt;It is a structural absence of &lt;em&gt;structured&lt;/em&gt; data — the kind that AI agents can query, validate, and reason with.&lt;/p&gt;

&lt;p&gt;The raw material exists. It has existed for over a century. It sits in the public domain, digitized by libraries and archives, waiting to be structured.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the public domain contains
&lt;/h2&gt;

&lt;p&gt;The British East Africa Protectorate agricultural reports from 1910-1922 document, county by county, which crops grew where, what yields looked like in drought years versus good years, which soil types supported what cultivation, and which traditional practices survived contact with colonial agricultural extension.&lt;/p&gt;

&lt;p&gt;The Kew Gardens Economic Botany Series from 1906-1920 contains botanical surveys of East African crops — sorghum, millet, cassava, cowpea, moringa — with documented water requirements, storage characteristics, and soil tolerances.&lt;/p&gt;

&lt;p&gt;The East Africa Meteorological Department records from 1900-1940 show rainfall patterns before the satellite era: where the long rains reliably arrive, where they don't, where the variability is structurally high.&lt;/p&gt;

&lt;p&gt;These documents are free. They are in the public domain. They are not behind paywalls. They are in libraries.&lt;/p&gt;

&lt;h2&gt;
  
  
  The structural absence
&lt;/h2&gt;

&lt;p&gt;The problem: they are in the format of 1910.&lt;/p&gt;

&lt;p&gt;Scanned PDFs. Handwritten tables. Narrative reports in colonial English. Measurement systems that predated standardization.&lt;/p&gt;

&lt;p&gt;No AI agent built in 2025 can query them the way it needs to. "What is the planting calendar for sorghum in semi-arid Kenya?" requires that someone has extracted, structured, validated, and made available the answer in a format that agents can use.&lt;/p&gt;

&lt;p&gt;That structured layer is what's missing. Not the underlying knowledge.&lt;/p&gt;

&lt;h2&gt;
  
  
  What structured public domain data enables
&lt;/h2&gt;

&lt;p&gt;The MCP servers in the East Africa coordination stack (&lt;a href="https://pypi.org/project/wapimaji-mcp/" rel="noopener noreferrer"&gt;wapimaji-mcp&lt;/a&gt;, &lt;a href="https://pypi.org/project/kilimo-mcp/" rel="noopener noreferrer"&gt;kilimo-mcp&lt;/a&gt;, &lt;a href="https://pypi.org/project/bima-mcp/" rel="noopener noreferrer"&gt;bima-mcp&lt;/a&gt;) need grounded knowledge to reason correctly.&lt;/p&gt;

&lt;p&gt;When a farmer asks an AI agent about optimal planting dates for a semi-arid county, the agent needs historical knowledge of rainfall patterns and crop tolerances — not just a general LLM approximation.&lt;/p&gt;

&lt;p&gt;That knowledge exists in the 1910 Kew surveys. The work is structuring it so the MCP can use it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What was structured this week
&lt;/h2&gt;

&lt;p&gt;Six public domain datasets now available on HuggingFace:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;East Africa agricultural data&lt;/strong&gt; — crop profiles, rainfall zones, soil types from USDA and Kew (1906-1922)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Swahili historical corpus&lt;/strong&gt; — Krapf 1882, Taylor 1891, Steere 1870: the vocabulary of East African coordination in the language 200 million people speak&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;East Africa health historical&lt;/strong&gt; — disease patterns, altitude factors, traditional medicine documentation (1895-1920)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;East Africa legal and land tenure&lt;/strong&gt; — customary systems, colonial legislation, dispute resolution (pre-1928)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Africa historical maps catalog&lt;/strong&gt; — metadata for PD maps from Library of Congress, National Archives, Kew (1688-1925)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open government climate catalog&lt;/strong&gt; — NASA, NOAA, USDA datasets structured for African agricultural use&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All public domain. All structured for AI agent use. All connected to the coordination infrastructure stack.&lt;/p&gt;

&lt;p&gt;The knowledge infrastructure problem in Africa is not a lack of knowledge. It is a lack of structured access to knowledge that already exists.&lt;/p&gt;

&lt;p&gt;Public domain works published before 1928 are the closest thing to free raw material in the information economy. The opportunity is not to extract value from them. It is to structure them so they can flow.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;These datasets are available at &lt;a href="https://huggingface.co/gmahia" rel="noopener noreferrer"&gt;huggingface.co/gmahia&lt;/a&gt;. Related coordination tools at &lt;a href="https://pypi.org/user/gmahia/" rel="noopener noreferrer"&gt;pypi.org/user/gmahia&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>africa</category>
      <category>opendata</category>
      <category>agriculture</category>
    </item>
    <item>
      <title>Building Coordination Infrastructure: What 32 MCP Servers Without a Bus Look Like</title>
      <dc:creator>Gabriel Mahia</dc:creator>
      <pubDate>Mon, 03 Aug 2026 10:00:00 +0000</pubDate>
      <link>https://dev.to/gabrielmahia/building-coordination-infrastructure-what-32-mcp-servers-without-a-bus-look-like-243c</link>
      <guid>https://dev.to/gabrielmahia/building-coordination-infrastructure-what-32-mcp-servers-without-a-bus-look-like-243c</guid>
      <description>&lt;p&gt;Thirty-two MCP servers for Kenya's coordination domains.&lt;/p&gt;

&lt;p&gt;Water. Health. Agriculture. Insurance. Land. Education. Transport. Tax. Labor. Market prices.&lt;/p&gt;

&lt;p&gt;Each one works. None talks to any other.&lt;/p&gt;

&lt;p&gt;This is what 32 isolated tools looks like in practice: a CHW in Kisumu flags a cholera cluster. The water quality system doesn't know. The county procurement system doesn't know. The emergency medicine supply chain doesn't know. The tools that need to respond are all present. The coordination between them doesn't exist.&lt;/p&gt;

&lt;h2&gt;
  
  
  The architectural problem
&lt;/h2&gt;

&lt;p&gt;The Model Context Protocol ecosystem is growing fast. For most of the world, it's growing in domains that already have coordination infrastructure: calendar apps, email clients, project management tools. These tools coordinate with each other through years of API integrations, webhooks, Zapier connections, and shared data stores.&lt;/p&gt;

&lt;p&gt;African coordination domains don't have that legacy. They're being built now, from scratch, on MCP.&lt;/p&gt;

&lt;p&gt;That means the coordination layer has to be built at the same time.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a coordination layer looks like at the MCP level
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/gabrielmahia/africa-coord-bus" rel="noopener noreferrer"&gt;&lt;code&gt;africa-coord-bus&lt;/code&gt;&lt;/a&gt; defines a &lt;code&gt;CoordinationEvent&lt;/code&gt; — a standard cross-domain signal schema — and an &lt;code&gt;EventBus&lt;/code&gt; that routes events to the tools that need to respond.&lt;/p&gt;

&lt;p&gt;The routing table is explicit:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Trigger&lt;/th&gt;
&lt;th&gt;Cascade&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;water.drought_alert&lt;/code&gt; (Warning+)&lt;/td&gt;
&lt;td&gt;bima-mcp, kilimo-mcp, soko-mcp&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;water.drought_alert&lt;/code&gt; (Alert+)&lt;/td&gt;
&lt;td&gt;+ afya-mcp, county-mcp&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;health.disease_outbreak&lt;/code&gt; (cholera)&lt;/td&gt;
&lt;td&gt;wapimaji-mcp water quality check&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;agriculture.price_spike&lt;/code&gt; (&amp;gt;30%)&lt;/td&gt;
&lt;td&gt;afya-mcp food security watch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;water.flood_alert&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;afya-mcp waterborne watch, county-mcp&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Custom rules take three lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;africa_coord_bus&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RoutingRule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EventDomain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EventSeverity&lt;/span&gt;

&lt;span class="n"&gt;bus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;routing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;RoutingRule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;locust→emergency_procurement&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;trigger_domain&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;EventDomain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AGRICULTURE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;trigger_event_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;locust_swarm&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;trigger_min_severity&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;EventSeverity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ALERT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;target_actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fomu-mcp.emergency_procurement&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;county-mcp.agriculture_alert&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The composable coordination stack
&lt;/h2&gt;

&lt;p&gt;The pattern that's emerging for East Africa:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Public domain datasets (HuggingFace)
        │ grounding knowledge
        ▼
32 MCP servers (PyPI) ←── africa-coord-bus
        │
        ▼
A2A + ADK agents
        │
        ▼
Streamlit coordination interfaces
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each layer is replaceable. The models are replaceable. The MCP servers are replaceable. What persists is the coordination architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;africa-coord-bus
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Source: &lt;a href="https://github.com/gabrielmahia/africa-coord-bus" rel="noopener noreferrer"&gt;github.com/gabrielmahia/africa-coord-bus&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The coordination gap was the last missing layer. It's now installable.&lt;/p&gt;

&lt;p&gt;Source: &lt;a href="https://pypi.org/project/africa-coord-bus/" rel="noopener noreferrer"&gt;africa-coord-bus on PyPI&lt;/a&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>africa</category>
      <category>coordination</category>
      <category>python</category>
    </item>
    <item>
      <title>MCP, A2A, and Google ADK for East Africa: What the Coordination Stack Looks Like</title>
      <dc:creator>Gabriel Mahia</dc:creator>
      <pubDate>Fri, 31 Jul 2026 10:00:00 +0000</pubDate>
      <link>https://dev.to/gabrielmahia/mcp-a2a-and-google-adk-for-east-africa-what-the-coordination-stack-looks-like-3f0n</link>
      <guid>https://dev.to/gabrielmahia/mcp-a2a-and-google-adk-for-east-africa-what-the-coordination-stack-looks-like-3f0n</guid>
      <description>&lt;p&gt;Three protocols landed in 2024 that change what AI agents can do in production: MCP (Model Context Protocol), A2A (Agent-to-Agent), and Google ADK (Agent Development Kit).&lt;/p&gt;

&lt;p&gt;The question for Africa's coordination infrastructure is not whether these protocols are technically interesting. The question is: what does the absence of domain-specific implementations mean for the coordination problems — health, water, agriculture, land, education — that remain unsolved at scale?&lt;/p&gt;

&lt;h2&gt;
  
  
  The structural absence
&lt;/h2&gt;

&lt;p&gt;Most MCP implementations connect to platforms that already exist in rich countries: Slack, Google Calendar, GitHub, Stripe, Salesforce. The ecosystems those tools coordinate are already coordinated. The problem is solved.&lt;/p&gt;

&lt;p&gt;The structural absence is in the domains where coordination is genuinely broken:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A community health worker in Turkana County manages 1,200 households with a paper register. No MCP server for CHW coordination.&lt;/li&gt;
&lt;li&gt;A smallholder farmer in Embu has no way to know today's market price at the Meru collection point before deciding to sell. No MCP server for farm-gate price information.&lt;/li&gt;
&lt;li&gt;Drought early warning data exists (NASA NDVI, NOAA CHIRPS) but there is no structured AI-accessible interface to it. No MCP server for drought intelligence.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are not technical problems. They are data structuring and interface design problems. The protocols exist. The domain implementations don't.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the stack looks like
&lt;/h2&gt;

&lt;p&gt;The East Africa coordination stack now includes 31 MCP servers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Payments&lt;/strong&gt;: M-Pesa API via Daraja (mpesa-mcp)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Water/drought&lt;/strong&gt;: Satellite data integration (wapimaji-mcp)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agriculture&lt;/strong&gt;: Market coordination, crop advisory (kilimo-mcp, soko-mcp)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parametric insurance&lt;/strong&gt;: Satellite-triggered coverage (bima-mcp)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Health&lt;/strong&gt;: County health service coordination (afya-mcp, county-mcp)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Land&lt;/strong&gt;: Registry coordination (ardhi-mcp)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tax compliance&lt;/strong&gt;: Kenya Revenue Authority (kra-mcp)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Capital markets&lt;/strong&gt;: NSE data access (faida-mcp)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Labor rights&lt;/strong&gt;: Worker compliance (haki-ya-kazi-mcp)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Language&lt;/strong&gt;: Swahili NLP infrastructure (swahili-civic-nlp, tafsiri-mcp)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The A2A pattern enables agents built on these servers to coordinate without bespoke integration code. The ADK pattern provides the framework for agents that can plan multi-step tasks — necessary for coordination workflows spanning multiple API calls and decisions.&lt;/p&gt;

&lt;h2&gt;
  
  
  The architecture gap this addresses
&lt;/h2&gt;

&lt;p&gt;The composable model future assumes domain knowledge is accessible to AI agents through structured interfaces. For most African coordination domains, it is not.&lt;/p&gt;

&lt;p&gt;The problem is not a model problem. GPT-4, Claude, and Gemini are accessible. The problem is that there is no structured interface between those models and the data that would make them useful for a CHW in Turkana, a farmer in Embu, or a water officer in Wajir.&lt;/p&gt;

&lt;p&gt;MCP, A2A, and ADK are the protocol layer. The East Africa implementations are the domain layer. The work is connecting them.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;All servers available at &lt;a href="https://pypi.org/user/gmahia/" rel="noopener noreferrer"&gt;pypi.org/user/gmahia&lt;/a&gt; and indexed at Glama.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>africa</category>
      <category>python</category>
    </item>
    <item>
      <title>Build Your First East Africa MCP Server in 30 Minutes</title>
      <dc:creator>Gabriel Mahia</dc:creator>
      <pubDate>Tue, 28 Jul 2026 10:00:00 +0000</pubDate>
      <link>https://dev.to/gabrielmahia/build-your-first-east-africa-mcp-server-in-30-minutes-2nj6</link>
      <guid>https://dev.to/gabrielmahia/build-your-first-east-africa-mcp-server-in-30-minutes-2nj6</guid>
      <description>&lt;p&gt;Every tool in the East Africa coordination infrastructure stack started from the same scaffold. Here's exactly how to build and publish one yourself.&lt;/p&gt;

&lt;h2&gt;
  
  
  What You're Building
&lt;/h2&gt;

&lt;p&gt;An MCP server is a Python package that exposes tools to AI assistants. When a user installs it and connects it to Claude, the AI can call your tools as naturally as answering a question.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;your-mcp-server
&lt;span class="c"&gt;# Then Claude can:&lt;/span&gt;
&lt;span class="c"&gt;# "Check NHIF coverage for outpatient surgery" → calls your tool → returns structured result&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 1: Set Up the Project (2 min)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;your-mcp-server/
├── src/
│   └── your_package/
│       ├── __init__.py
│       └── main.py
├── pyproject.toml
├── README.md
└── .github/
    └── workflows/
        └── publish.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;your-mcp-server &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;your-mcp-server
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; src/your_package
&lt;span class="nb"&gt;touch &lt;/span&gt;src/your_package/__init__.py src/your_package/main.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Write Your Tool (10 min)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# src/your_package/main.py
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;__future__&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;annotations&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Annotated&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fastmcp&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FastMCP&lt;/span&gt;

&lt;span class="n"&gt;mcp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FastMCP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your-mcp-server&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;instructions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Describe what your server does in one paragraph.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@mcp.tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;What this tool does in plain language. &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Include the Western parallel if applicable. &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Note if it uses DEMO data.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;your_tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;param1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Annotated&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Description of param1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;param2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Annotated&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Description of param2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Your logic here
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;result&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Processed &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;param1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;note&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DEMO — replace with real data source in production&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;source&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your-mcp-server&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;mcp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Configure pyproject.toml (3 min)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[build-system]&lt;/span&gt;
&lt;span class="py"&gt;requires&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="py"&gt;["setuptools&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;61.0&lt;/span&gt;&lt;span class="s"&gt;"]&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="py"&gt;build-backend&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"setuptools.build_meta"&lt;/span&gt;  &lt;span class="c"&gt;# ← exact string, no variation&lt;/span&gt;

&lt;span class="nn"&gt;[project]&lt;/span&gt;
&lt;span class="py"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"your-mcp-server"&lt;/span&gt;
&lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.1.0"&lt;/span&gt;
&lt;span class="py"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"One-line description"&lt;/span&gt;
&lt;span class="py"&gt;authors&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="py"&gt;[{name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Your Name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;email&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"you@example.com"&lt;/span&gt;&lt;span class="err"&gt;}]&lt;/span&gt;
&lt;span class="py"&gt;license&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="py"&gt;text&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"MIT"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="py"&gt;readme&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"README.md"&lt;/span&gt;
&lt;span class="py"&gt;requires-python&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="py"&gt;"&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;3.9&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="py"&gt;dependencies&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="py"&gt;["fastmcp&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="s"&gt;"]&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;
&lt;span class="nn"&gt;[project.scripts]&lt;/span&gt;
&lt;span class="py"&gt;your-mcp-server&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"your_package.main:main"&lt;/span&gt;  &lt;span class="c"&gt;# CLI entry point&lt;/span&gt;

&lt;span class="nn"&gt;[tool.setuptools.packages.find]&lt;/span&gt;
&lt;span class="py"&gt;where&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"src"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="c"&gt;# ← required for src/ layout&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Common mistake:&lt;/strong&gt; &lt;code&gt;build-backend = "setuptools.backends.legacy:build"&lt;/code&gt; is not valid. Use exactly &lt;code&gt;"setuptools.build_meta"&lt;/code&gt;. This error causes &lt;code&gt;python -m build&lt;/code&gt; to fail silently in CI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Set Up CI Publishing (5 min)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Option A: API Token (faster)&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a PyPI API token at &lt;a href="https://pypi.org/manage/account/#api-tokens" rel="noopener noreferrer"&gt;pypi.org/manage/account/#api-tokens&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Add as &lt;code&gt;PYPI_API_TOKEN&lt;/code&gt; in your GitHub repo → Settings → Secrets&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Option B: OIDC Trusted Publisher (more secure, recommended)&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create the package on PyPI first (one push via token)&lt;/li&gt;
&lt;li&gt;Go to &lt;code&gt;pypi.org/manage/project/{name}/settings/publishing/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Add GitHub Actions publisher: owner, repo, &lt;code&gt;publish.yml&lt;/code&gt;, environment &lt;code&gt;pypi&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;.github/workflows/publish.yml:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Publish to PyPI&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;v*"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;publish&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-python@v5&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;python-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3.11"&lt;/span&gt;&lt;span class="pi"&gt;}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pip install build&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;python -m build&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pypa/gh-action-pypi-publish@release/v1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.PYPI_API_TOKEN }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 5: Publish (2 min)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git init &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; git add &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"initial commit"&lt;/span&gt;
git remote add origin https://github.com/yourusername/your-mcp-server
git push &lt;span class="nt"&gt;-u&lt;/span&gt; origin main

git tag v0.1.0 &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; git push origin v0.1.0
&lt;span class="c"&gt;# → GitHub Actions runs → pip install your-mcp-server works in 2-3 minutes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 6: Connect to Claude (1 min)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install&lt;/span&gt;
pip &lt;span class="nb"&gt;install &lt;/span&gt;your-mcp-server

&lt;span class="c"&gt;# Add to Claude Code&lt;/span&gt;
claude mcp add myserver &lt;span class="nt"&gt;--&lt;/span&gt; your-mcp-server

&lt;span class="c"&gt;# Test&lt;/span&gt;
claude &lt;span class="s2"&gt;"Use myserver to process X"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  East Africa Design Patterns
&lt;/h2&gt;

&lt;p&gt;A few patterns specific to building for this context:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Trust integrity:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;result&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;note&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DEMO — Synthetic data for educational purposes. Not operational guidance.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;source&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your-mcp-server. Research basis: [cite your source]&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Swahili/English bilingual errors:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;error&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hitilafu / Error: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;. Jaribu tena / Try again.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Version bump workflow:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Edit pyproject.toml → version = "0.2.0"&lt;/span&gt;
git commit &lt;span class="nt"&gt;-am&lt;/span&gt; &lt;span class="s2"&gt;"bump: v0.2.0"&lt;/span&gt;
git tag v0.2.0 &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; git push origin main &lt;span class="nt"&gt;--tags&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's the complete cycle. Every MCP server in the &lt;a href="https://gabrielmahia.github.io" rel="noopener noreferrer"&gt;East Africa coordination stack&lt;/a&gt; was built and published with exactly this scaffold.&lt;/p&gt;




&lt;p&gt;Full portfolio and all 12 packages: &lt;a href="https://gabrielmahia.github.io" rel="noopener noreferrer"&gt;gabrielmahia.github.io&lt;/a&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>python</category>
      <category>tutorial</category>
      <category>africa</category>
    </item>
    <item>
      <title>Constitutional Rights in Swahili: Building a Multi-Agent Debate System</title>
      <dc:creator>Gabriel Mahia</dc:creator>
      <pubDate>Sat, 25 Jul 2026 10:00:00 +0000</pubDate>
      <link>https://dev.to/gabrielmahia/constitutional-rights-in-swahili-building-a-multi-agent-debate-system-g0j</link>
      <guid>https://dev.to/gabrielmahia/constitutional-rights-in-swahili-building-a-multi-agent-debate-system-g0j</guid>
      <description>&lt;p&gt;40%+ of Kenyans don't know their constitutional rights. Not because the rights don't exist — Kenya's 2010 constitution is among the most progressive in Africa — but because the information is locked in dense legal language, available only in English, and not easily accessible through any institutional channel.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;hakiyangu&lt;/code&gt; (haki = rights, yangu = mine — "my rights") is a multi-agent constitutional debate system that presents both the government's position and the citizen's rights on any constitutional question, in Swahili or English.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Research Basis
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;arXiv:2305.19118 — Liang et al. (2023):&lt;/strong&gt; "Encouraging Divergent Thinking in Large Language Models through Debate"&lt;/p&gt;

&lt;p&gt;This paper demonstrated that when multiple AI agents argue opposing positions on a question, the final synthesized answer is measurably less biased and more accurate than a single-agent response. The adversarial format forces the AI to consider the strongest version of each position before synthesizing.&lt;/p&gt;

&lt;p&gt;For constitutional rights questions, this is particularly important: the government has legitimate interests, and citizens have constitutional protections. Neither perspective alone gives a complete picture.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Three-Agent Architecture
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Agent 1: Government Legal Officer
&lt;/span&gt;&lt;span class="n"&gt;gov_response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;call_gemini&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;system&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;You are a Senior Government Legal Officer defending the Kenya government 
            position on constitutional rights. Be factual. Cite actual articles.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Citizen question: &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Agent 2: Human Rights Advocate  
&lt;/span&gt;&lt;span class="n"&gt;cit_response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;call_gemini&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;system&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;You are a Human Rights Advocate defending citizen constitutional rights.
            Cite actual articles. Acknowledge government has valid interests.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Citizen question: &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Agent 3: Constitutional Law Lecturer (synthesis)
&lt;/span&gt;&lt;span class="n"&gt;synthesis&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;call_gemini&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;system&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;You are an independent Constitutional Law Lecturer at University of Nairobi.
            Synthesize both sides. Focus on: what can the citizen do, what are their 
            strongest legal protections, when to seek formal legal help.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Government argued: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;gov_response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;
Rights advocate argued: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;cit_response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each agent has a defined role and is explicitly instructed to cite the actual Kenya Constitution articles, not summarize them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rights Covered
&lt;/h2&gt;

&lt;p&gt;Six rights from the Kenya Constitution 2010:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Freedom of Expression (Article 33)&lt;/li&gt;
&lt;li&gt;Right to Property (Article 40)&lt;/li&gt;
&lt;li&gt;Right to a Fair Trial (Article 50)&lt;/li&gt;
&lt;li&gt;Freedom from Discrimination (Article 27)&lt;/li&gt;
&lt;li&gt;Right to Education (Article 43)&lt;/li&gt;
&lt;li&gt;Freedom of Movement (Article 26)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each right has pre-loaded context, the government's constitutional basis for limitations, and the citizen's strongest protections.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Error Handling Lesson
&lt;/h2&gt;

&lt;p&gt;The original &lt;code&gt;haki-debate-ai&lt;/code&gt; (now &lt;code&gt;hakiyangu&lt;/code&gt;) had no try/except around the three Gemini calls. When the API returned HTTP 404 (due to a &lt;code&gt;v1beta&lt;/code&gt; vs &lt;code&gt;v1&lt;/code&gt; endpoint change), the error surfaced as a full Streamlit traceback — including file paths and code snippets.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Before: one unprotected call, full crash on error
&lt;/span&gt;&lt;span class="n"&gt;gov_response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;call_gemini&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gov_system&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# After: wrapped calls with Swahili error messages
&lt;/span&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;gov_response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;call_gemini&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gov_system&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;gov_response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;⚠️ Hitilafu: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Users see "Hitilafu ya API (404). Jaribu tena baadaye. / API error. Please try again later." — not a Python traceback. Production apps owe users graceful degradation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploy It
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Streamlit Cloud: github.com/gabrielmahia/hakiyangu&lt;/span&gt;
&lt;span class="c"&gt;# Secret: GOOGLE_API_KEY = "your-gemini-key"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Try it at hakiyangu.streamlit.app &lt;em&gt;(setup in progress)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/gabrielmahia/hakiyangu" rel="noopener noreferrer"&gt;github.com/gabrielmahia/hakiyangu&lt;/a&gt; · CC BY-NC-ND 4.0&lt;/p&gt;

</description>
      <category>civictech</category>
      <category>africa</category>
      <category>ai</category>
      <category>swahili</category>
    </item>
    <item>
      <title>The 500x Data Gap: Why AI Makes 4x More Errors in Swahili Than English</title>
      <dc:creator>Gabriel Mahia</dc:creator>
      <pubDate>Wed, 22 Jul 2026 10:00:00 +0000</pubDate>
      <link>https://dev.to/gabrielmahia/the-500x-data-gap-why-ai-makes-4x-more-errors-in-swahili-than-english-18aa</link>
      <guid>https://dev.to/gabrielmahia/the-500x-data-gap-why-ai-makes-4x-more-errors-in-swahili-than-english-18aa</guid>
      <description>&lt;p&gt;There's a paper you need to read if you're building AI for African languages: arXiv:2509.04516.&lt;/p&gt;

&lt;p&gt;Its finding: AI models produce approximately &lt;strong&gt;4 times more errors in Swahili than in English&lt;/strong&gt;. The root cause isn't model architecture. It's training data. Swahili has approximately 500 times less representation in Common Crawl (the primary web data source for most LLMs) than English.&lt;/p&gt;

&lt;p&gt;500x less data → 4x more errors → every Swahili-language AI product is starting from a significant accuracy deficit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Window Is Closing
&lt;/h2&gt;

&lt;p&gt;This is the part that urgency-frameworks often get wrong. It's not "act now because the problem is bad." It's &lt;strong&gt;act now because the window for establishing data primacy is narrowing&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;AI development has entered a self-improving phase. Anthropic's internal research (May 2026) documents that 80%+ of merged code at major AI labs is now AI-authored, with engineers deploying 8x more code per day than two years prior. This trajectory compounds.&lt;/p&gt;

&lt;p&gt;Whatever language advantages exist today will be amplified by self-improvement. Swahili data that enters the training pipeline this year compounds forward. Data that enters in 2028 competes with a much more entrenched English-language advantage.&lt;/p&gt;

&lt;p&gt;The window for establishing Swahili data primacy is 12–18 months. Not years.&lt;/p&gt;

&lt;h2&gt;
  
  
  What We've Built
&lt;/h2&gt;

&lt;p&gt;Four Swahili NLP datasets, all CC BY 4.0, all on HuggingFace:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;swahili-civic-nlp&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Annotated sentences covering government services, constitutional rights, M-PESA financial terms, county administration. Ground truth for civic AI agents that need to understand Swahili queries about rights and services.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;kenya-agricultural-qa&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Q&amp;amp;A pairs covering crop disease (MSV, FAW), market prices, planting calendars, livestock health. Grounded in KALRO/KEPHIS data. For AI advisors that need to answer farming questions accurately in Swahili.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;kenya-legal-nlp&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Annotated Kenya legal documents — Constitution, Employment Act, Land Act — with NER labels (PERSON, ORG, LAW, DATE) and QA pairs. For legal information retrieval in Swahili.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;kenya-civic-data&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
County government data, budget allocations, public service metrics. Structured for relation extraction and question answering on civic content.&lt;/p&gt;

&lt;h2&gt;
  
  
  The LINGUA Africa Application
&lt;/h2&gt;

&lt;p&gt;The LINGUA Africa grant (Masakhane × Microsoft × Gates Foundation) funds exactly this gap: Swahili-native AI infrastructure for East African financial inclusion, civic accountability, and education.&lt;/p&gt;

&lt;p&gt;The proposed deliverables:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;4 additional Swahili datasets (financial Q&amp;amp;A, health corpus v2, agricultural Q&amp;amp;A v2, civic NLP v2) — 95,000+ annotated examples&lt;/li&gt;
&lt;li&gt;Fine-tuned model evaluated on IrokoBench (arXiv:2406.03368), the African language benchmark&lt;/li&gt;
&lt;li&gt;Voice-native Swahili agent using GPT-Realtime-Whisper&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Submitted June 2026.&lt;/p&gt;

&lt;h2&gt;
  
  
  How You Can Help
&lt;/h2&gt;

&lt;p&gt;Every Swahili developer, linguist, or domain expert who contributes to this dataset pool helps close the gap. The datasets are CC BY 4.0 — use them, extend them, cite them.&lt;/p&gt;

&lt;p&gt;If you have access to Swahili domain-specific text (agricultural extension materials, court transcripts, medical protocols, government forms), reach out: &lt;a href="mailto:contact@aikungfu.dev"&gt;contact@aikungfu.dev&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The 200 million Swahili speakers of East Africa deserve AI that works as well for them as it does for English speakers. That outcome requires intentional data work, now.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://huggingface.co/gmahia" rel="noopener noreferrer"&gt;HuggingFace datasets: gmahia&lt;/a&gt;&lt;/p&gt;

</description>
      <category>nlp</category>
      <category>africa</category>
      <category>ai</category>
      <category>swahili</category>
    </item>
    <item>
      <title>3,000 Patients Per Worker: Can AI Support Kenya's Community Health Workers?</title>
      <dc:creator>Gabriel Mahia</dc:creator>
      <pubDate>Sun, 19 Jul 2026 10:00:00 +0000</pubDate>
      <link>https://dev.to/gabrielmahia/3000-patients-per-worker-can-ai-support-kenyas-community-health-workers-mln</link>
      <guid>https://dev.to/gabrielmahia/3000-patients-per-worker-can-ai-support-kenyas-community-health-workers-mln</guid>
      <description>&lt;p&gt;Kenya has approximately 100,000 Community Health Workers (CHWs — locally called Community Health Extension Workers, or CHEWs). They cover a population of 54 million. That's roughly one CHW per 540 people, but in rural areas the ratio reaches 3,000:1.&lt;/p&gt;

&lt;p&gt;These workers are the first and often only medical contact for millions of Kenyans. They do triage. They decide who needs a hospital referral. They counsel on pregnancy, malnutrition, fever, diarrhoea. They work from memory and a printed protocol card.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;afyanipoa&lt;/code&gt; (afya nzuri = good health in Swahili, "poa" = cool) is an AI clinical co-pilot for these workers.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Research Basis
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;arXiv:2408.17216 — "Democratizing AI in Africa: Federated Learning for Low-Resource Edge Devices" (2024)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This paper demonstrated that federated learning can be deployed on Raspberry Pi-class devices (the computing tier of affordable Android phones) in 5 African countries simultaneously, achieving acceptable model accuracy without centralized data collection. The implication: clinical AI doesn't require cloud connectivity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WHO Community Health Workers Reference Group (2022):&lt;/strong&gt; The WHO documents that CHW programs are most effective when workers have access to real-time decision support — but most programs only provide printed job aids updated annually.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Kenya MOH CHEW Curriculum:&lt;/strong&gt; The Kenya Ministry of Health publishes the official training curriculum for CHEWs. The integrated management protocols for fever, cough, diarrhoea, ANC, and malnutrition are well-defined and systematizable.&lt;/p&gt;

&lt;h2&gt;
  
  
  What afyanipoa Does
&lt;/h2&gt;

&lt;p&gt;The app has three layers:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Protocol library (always available, no AI needed)&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Embedded Kenya MOH protocols for 8 conditions: fever, cough, diarrhoea, malnutrition, ANC, family planning, mental health, TB screening. Danger signs, referral triggers, dosing by age/weight. Zero API calls required.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. AI clinical guidance (when API key is configured)&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
A CHW describes a patient's complaint in Swahili. The AI synthesizes the relevant protocol sections with the specific presentation and returns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ISHARA ZA HATARI / DANGER SIGNS (check first)&lt;/li&gt;
&lt;li&gt;TATHMINI / ASSESSMENT (what to examine)&lt;/li&gt;
&lt;li&gt;MATIBABU / IMMEDIATE ACTION&lt;/li&gt;
&lt;li&gt;PELEKA / REFERRAL (when, where, why)&lt;/li&gt;
&lt;li&gt;FUATILIA / FOLLOW-UP&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Emergency contacts (always visible)&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
0800 720 571 (Kenya health emergency line), county referral hospital numbers, maternal emergency contacts.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Safety Architecture
&lt;/h2&gt;

&lt;p&gt;This is safety-critical software. The design decisions reflect that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DEMO label: visible on every screen
AI output: labeled "decision support, not diagnosis"
Danger signs: displayed FIRST, before any AI output
Referral bias: when in doubt, the prompt leans toward referral
Emergency contacts: persistent, not hidden in menus
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Gemini prompt explicitly instructs the model:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"When in doubt between management at home and referral, recommend referral. A missed referral in the field has worse consequences than an unnecessary one. This is decision SUPPORT — the CHW makes the final call."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The Endpoint Fix
&lt;/h2&gt;

&lt;p&gt;One lesson from this deployment: &lt;strong&gt;always use the stable &lt;code&gt;/v1/&lt;/code&gt; endpoint, not &lt;code&gt;/v1beta/&lt;/code&gt;.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Wrong — returns 404 for gemini-2.0-flash
&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;# Right — try v1 first, fall back to v1beta
&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;ver&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;v1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;v1beta&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;generativelanguage.googleapis.com/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ver&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/models/gemini-2.0-flash:generateContent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# ... call ...
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;HTTPError&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;ver&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;v1beta&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;raise&lt;/span&gt;
        &lt;span class="k"&gt;continue&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This pattern has since been applied to all Gemini-enabled apps in this portfolio.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploy It Today
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Streamlit Cloud — free tier&lt;/span&gt;
&lt;span class="c"&gt;# Repo: github.com/gabrielmahia/afyanipoa&lt;/span&gt;
&lt;span class="c"&gt;# Secret: GOOGLE_API_KEY = "your-gemini-key"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Get a free Gemini API key at &lt;a href="https://console.cloud.google.com" rel="noopener noreferrer"&gt;console.cloud.google.com&lt;/a&gt; → Gemini API → Enable → Create key.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/gabrielmahia/afyanipoa" rel="noopener noreferrer"&gt;github.com/gabrielmahia/afyanipoa&lt;/a&gt; · CC BY-NC-ND 4.0&lt;/p&gt;

</description>
      <category>health</category>
      <category>africa</category>
      <category>python</category>
      <category>ai</category>
    </item>
    <item>
      <title>Reputation Portability: The Missing Infrastructure for Economic Mobility</title>
      <dc:creator>Gabriel Mahia</dc:creator>
      <pubDate>Thu, 16 Jul 2026 10:00:00 +0000</pubDate>
      <link>https://dev.to/gabrielmahia/reputation-portability-the-missing-infrastructure-for-economic-mobility-hko</link>
      <guid>https://dev.to/gabrielmahia/reputation-portability-the-missing-infrastructure-for-economic-mobility-hko</guid>
      <description>&lt;p&gt;A skilled plumber in Chicago can move to Los Angeles and immediately find work. Her Yelp reviews, contractor license, and Angie's List history travel with her. Strangers trust her before she's done a single job.&lt;/p&gt;

&lt;p&gt;A skilled mason in Mombasa cannot take her reputation to Nairobi. Trust is tribal and local. Hiring defaults to personal networks. The most talented people outside existing networks are invisible.&lt;/p&gt;

&lt;p&gt;This is not a cultural problem. It's an infrastructure problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Reputation Portability Infrastructure Looks Like
&lt;/h2&gt;

&lt;p&gt;In mature economies, the infrastructure exists in fragments:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Uber/Lyft:&lt;/strong&gt; Star ratings that follow a driver across cities&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LinkedIn:&lt;/strong&gt; Endorsements and work history that cross borders&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;BBB (Better Business Bureau):&lt;/strong&gt; Verified complaint and resolution history&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Angie's List / Thumbtack:&lt;/strong&gt; Job completion ratings for home services&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Upwork JSS:&lt;/strong&gt; Job Success Score based on completed contracts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Professional licensing boards:&lt;/strong&gt; Verifiable credentials (doctor, electrician, contractor)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each of these solves the same problem: how do you compress trust between strangers at scale?&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sifa-mcp&lt;/code&gt; (Sifa = reputation/praise in Swahili) is a portable reputation MCP server that implements this infrastructure for East Africa's informal economy.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Trust Score Architecture
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sifa_mcp&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;create_worker_profile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;add_service_record&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;get_reputation_profile&lt;/span&gt;

&lt;span class="c1"&gt;# Create a portable profile
&lt;/span&gt;&lt;span class="n"&gt;profile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_worker_profile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;full_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Amina Odhiambo&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;phone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;0712345678&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;primary_skill&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;construction&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;sub_skills&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;masonry,tiling,plastering&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;location&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Mombasa&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;years_experience&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# → profile_id: "SFA-A3F2B19C4E1D"
&lt;/span&gt;
&lt;span class="c1"&gt;# Add a completed job
&lt;/span&gt;&lt;span class="nf"&gt;add_service_record&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;profile_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SFA-A3F2B19C4E1D&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;client_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ABC Contractors&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;client_phone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;0722000000&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;service_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Kitchen tiling&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;duration_days&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;payment_kes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;15000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;client_rating&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Check trust for a new employer
&lt;/span&gt;&lt;span class="n"&gt;profile_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_reputation_profile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;profile_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SFA-A3F2B19C4E1D&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;requester_context&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;employer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# → trust_tier: "ESTABLISHED"
# → recommendation: "Good track record. Suitable for most engagements."
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Score Decomposition
&lt;/h2&gt;

&lt;p&gt;The trust score (0–100) is built from four signals:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Signal&lt;/th&gt;
&lt;th&gt;Max Points&lt;/th&gt;
&lt;th&gt;Rationale&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Job volume&lt;/td&gt;
&lt;td&gt;30&lt;/td&gt;
&lt;td&gt;Demonstrates activity, not just registration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Average quality&lt;/td&gt;
&lt;td&gt;35&lt;/td&gt;
&lt;td&gt;Client-rated — heaviest weight&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Verified records&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;Client OTP confirmation prevents fabrication&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tenure&lt;/td&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;td&gt;Long history = stability signal&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This maps directly to how humans assess trust: frequency + quality + verification + history.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Production Path
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;sifa-mcp&lt;/code&gt; is DEMO infrastructure. The in-memory profile store needs to be backed by a persistent database. More critically, production requires identity verification tied to Kenya's Huduma Number / NIIMS system — to prevent workers from fabricating verified records.&lt;/p&gt;

&lt;p&gt;The regulatory and identity infrastructure for this exists in Kenya. The coordination layer (portable reputation MCP) does not. That's the gap sifa-mcp fills — and the conversation it starts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why NITA Alignment Matters
&lt;/h2&gt;

&lt;p&gt;The skill categories in sifa-mcp are aligned with Kenya's National Industrial Training Authority trade classifications. This isn't accidental — NITA certification is the existing institutional trust anchor for skilled tradespeople. A sifa-mcp score that references NITA-certified training becomes part of a verifiable credential chain.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;sifa-mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://github.com/gabrielmahia/sifa-mcp" rel="noopener noreferrer"&gt;github.com/gabrielmahia/sifa-mcp&lt;/a&gt; · MIT License&lt;/p&gt;

</description>
      <category>africa</category>
      <category>labor</category>
      <category>python</category>
      <category>mcp</category>
    </item>
    <item>
      <title>Parametric Insurance: When Satellite Data Replaces the Claims Adjuster</title>
      <dc:creator>Gabriel Mahia</dc:creator>
      <pubDate>Mon, 13 Jul 2026 10:00:00 +0000</pubDate>
      <link>https://dev.to/gabrielmahia/parametric-insurance-when-satellite-data-replaces-the-claims-adjuster-2kdj</link>
      <guid>https://dev.to/gabrielmahia/parametric-insurance-when-satellite-data-replaces-the-claims-adjuster-2kdj</guid>
      <description>&lt;p&gt;Traditional crop insurance requires a claims adjuster to visit a farm, document damage, and approve a payout. In Kenya, where farms average 1.5 hectares and are scattered across 47 counties, this is economically impossible to do at scale.&lt;/p&gt;

&lt;p&gt;The result: 2.3% insurance penetration. One bad drought = financial ruin.&lt;/p&gt;

&lt;p&gt;Parametric insurance solves this by replacing the claims adjuster with satellite data.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Parametric Insurance Works
&lt;/h2&gt;

&lt;p&gt;Instead of insuring against "crop loss" (which requires verification), parametric insurance insures against a &lt;strong&gt;trigger event&lt;/strong&gt; — a measurable proxy for loss:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rainfall below 60mm in a 30-day growing period → automatic payout&lt;/li&gt;
&lt;li&gt;NDVI (normalized difference vegetation index) below 0.3 in July → payout&lt;/li&gt;
&lt;li&gt;Temperature above 38°C for 5+ consecutive days → payout&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No claims process. No adjuster. If the satellite says the trigger fired, the payout happens automatically — within 72 hours, direct to M-PESA.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Research Basis
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;ACRE Africa (2023):&lt;/strong&gt; ACRE (Agriculture and Climate Risk Enterprise) has facilitated over $200M in parametric insurance across 12 African countries. Their methodology uses NDMA (National Drought Management Authority) data as the primary trigger source for Kenya.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NDMA Kenya:&lt;/strong&gt; The NDMA publishes monthly county drought monitoring reports with rainfall deficit data, NDVI scores, and livestock condition indices. This is the data layer that makes parametric insurance possible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IRI (International Research Institute for Climate and Society):&lt;/strong&gt; El Niño/La Niña forecasting with 3-month lead time has been validated as a viable basis for planting-season insurance triggers in East Africa.&lt;/p&gt;

&lt;h2&gt;
  
  
  bima-mcp Implementation
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;bima_mcp&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;parametric_risk_score&lt;/span&gt;

&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parametric_risk_score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;county&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Nakuru&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;crop&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;maize&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;season&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;long_rains&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;coverage_kes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50000&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# → risk_tier: "MEDIUM",
# → trigger_threshold: "rainfall &amp;lt; 65mm in March-May growing period",
# → recommended_premium_kes: 3750,
# → payout_probability: 0.28,
# → data_source: "DEMO — modeled on NDMA county reports"
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Community Pool Tool
&lt;/h2&gt;

&lt;p&gt;One of the more interesting tools is &lt;code&gt;community_pool_calculator&lt;/code&gt;, which models informal risk-sharing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;bima_mcp&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;community_pool_calculator&lt;/span&gt;

&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;community_pool_calculator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;group_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;avg_farm_value_kes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;120000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;target_coverage_pct&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;drought_probability&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.25&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# → pool_size_needed_kes: 450000,
# → monthly_contribution_kes: 1500,
# → confidence_interval: "90% probability of full coverage for any single member in any given year"
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Chama groups (informal savings societies) are already the primary financial institution for millions of Kenyan women. Parametric pooling maps directly to existing behavior.&lt;/p&gt;

&lt;h2&gt;
  
  
  What bima-mcp Covers
&lt;/h2&gt;

&lt;p&gt;6 tools:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;nhif_coverage_query&lt;/code&gt; — NHIF benefit lookup by category&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;parametric_risk_score&lt;/code&gt; — NDMA-based crop risk scoring&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;microinsurance_comparison&lt;/code&gt; — product comparison across providers&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;community_pool_calculator&lt;/code&gt; — informal risk-sharing models&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;claim_eligibility&lt;/code&gt; — trigger-based eligibility check&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;insurance_gap_analysis&lt;/code&gt; — what's uninsured in a given county
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;bima-mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://github.com/gabrielmahia/bima-mcp" rel="noopener noreferrer"&gt;github.com/gabrielmahia/bima-mcp&lt;/a&gt; · MIT License&lt;/p&gt;

</description>
      <category>africa</category>
      <category>insurance</category>
      <category>python</category>
      <category>mcp</category>
    </item>
    <item>
      <title>The Information Asymmetry That Costs East African Farmers Billions</title>
      <dc:creator>Gabriel Mahia</dc:creator>
      <pubDate>Fri, 10 Jul 2026 10:00:00 +0000</pubDate>
      <link>https://dev.to/gabrielmahia/the-information-asymmetry-that-costs-east-african-farmers-billions-4imc</link>
      <guid>https://dev.to/gabrielmahia/the-information-asymmetry-that-costs-east-african-farmers-billions-4imc</guid>
      <description>&lt;p&gt;A trader drives from Nairobi to Nakuru on Monday morning. Before leaving, he checks wholesale prices at Wakulima Market. He knows maize is 12% higher in Nairobi this week than last.&lt;/p&gt;

&lt;p&gt;The farmer he buys from doesn't know this.&lt;/p&gt;

&lt;p&gt;That information gap is not accidental. It's structural, persistent, and extractable by anyone with market access. The World Bank estimated in 2016 that price information asymmetries account for 10–15% of post-harvest losses in Sub-Saharan Africa. For Kenya's 8M+ smallholder farmers, that's billions in foregone income annually.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;soko-mcp&lt;/code&gt; is a commodity price intelligence MCP server that begins to close this gap.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Research Basis
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Suri &amp;amp; Jack (2016):&lt;/strong&gt; M-PESA adoption in Kenya lifted 194,000 households out of poverty, disproportionately women — primarily through improved market access and ability to store value. The mechanism: reduced friction in market participation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;World Bank "ICT and Agricultural Markets" (2016):&lt;/strong&gt; In markets where farmers received SMS price updates, they achieved 8–10% higher farm-gate prices by timing sales or traveling to better markets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;EAGC East Africa Regional Market Monitor:&lt;/strong&gt; The East Africa Grain Council publishes weekly price data for 12 commodities across 8 countries. This data exists. It's just not integrated into tools farmers actually use.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Sell/Hold Problem
&lt;/h2&gt;

&lt;p&gt;The core decision a farmer faces post-harvest:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Should I sell my 50 bags of maize now, or store them for 2 months?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This requires three inputs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Current market price vs. historical average&lt;/li&gt;
&lt;li&gt;Expected price trajectory (seasonal pattern)&lt;/li&gt;
&lt;li&gt;Cost of storage (per bag per month)
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;soko_mcp&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sell_hold_decision&lt;/span&gt;

&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sell_hold_decision&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;commodity&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;maize&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;market&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;nakuru&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;quantity_bags&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;storage_cost_per_month_kes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;months_can_store&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# → recommendation: "HOLD 2 MONTHS"
# → expected_gain_kes: 8500 (net of storage costs)
# → confidence: "MODERATE"
# → caveat: "DEMO — based on synthetic seasonal patterns"
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What the Model Does
&lt;/h2&gt;

&lt;p&gt;The price model uses three signals:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Seasonal index:&lt;/strong&gt; Maize prices in Kenya follow a predictable post-harvest depression (March–May) and pre-harvest premium (October–December). This is well-documented in EAGC data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Regional spread:&lt;/strong&gt; Nairobi-Nakuru price differentials average 12–18% depending on road conditions and fuel costs. A farmer 200km from Nairobi can calculate whether the transport cost is worth it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Storage break-even:&lt;/strong&gt; At KES 500/bag/month, a 15% price increase over 2 months yields KES 7,500 net gain on 50 bags. If expected increase is 8%, don't store — sell now.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Trust Integrity Note
&lt;/h2&gt;

&lt;p&gt;All price data in &lt;code&gt;soko-mcp&lt;/code&gt; is &lt;strong&gt;DEMO — synthetic data&lt;/strong&gt; modeled on EAGC seasonal patterns. It does not connect to live market feeds.&lt;/p&gt;

&lt;p&gt;Production integration requires:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;EAGC API subscription (available to NGOs and research institutions)&lt;/li&gt;
&lt;li&gt;NAFIS (National Agriculture and Food Information System) real-time feeds&lt;/li&gt;
&lt;li&gt;Kenya National Bureau of Statistics retail price data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The model architecture is production-ready. The data connections are the next step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Five Tools
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;soko-mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;commodity_price_query&lt;/code&gt; — current price + 30-day trend&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;regional_price_comparison&lt;/code&gt; — prices across 8 East Africa markets&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;price_trend_analysis&lt;/code&gt; — 12-month historical pattern&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sell_hold_decision&lt;/code&gt; — net-of-storage recommendation&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;market_overview&lt;/code&gt; — full commodity dashboard&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://github.com/gabrielmahia/soko-mcp" rel="noopener noreferrer"&gt;github.com/gabrielmahia/soko-mcp&lt;/a&gt; · MIT License&lt;/p&gt;

</description>
      <category>agriculture</category>
      <category>africa</category>
      <category>python</category>
      <category>mcp</category>
    </item>
    <item>
      <title>Building parametric crop insurance with wapimaji-mcp and bima-mcp</title>
      <dc:creator>Gabriel Mahia</dc:creator>
      <pubDate>Mon, 06 Jul 2026 12:00:00 +0000</pubDate>
      <link>https://dev.to/gabrielmahia/building-parametric-crop-insurance-with-wapimaji-mcp-and-bima-mcp-1fmd</link>
      <guid>https://dev.to/gabrielmahia/building-parametric-crop-insurance-with-wapimaji-mcp-and-bima-mcp-1fmd</guid>
      <description>&lt;h1&gt;
  
  
  Building Parametric Crop Insurance with wapimaji-mcp and bima-mcp
&lt;/h1&gt;

&lt;p&gt;Traditional crop insurance in Kenya requires an adjuster to visit the farm, assess the damage, file a claim, wait for processing, and — maybe — receive a payout months after the harvest has already failed.&lt;/p&gt;

&lt;p&gt;Parametric insurance replaces the adjuster with satellite data. If drought reaches Phase 3 in your county, the policy pays out automatically. No adjuster. No waiting. No dispute.&lt;/p&gt;

&lt;p&gt;Here's how to build a basic parametric insurance agent using two MCP servers.&lt;/p&gt;

&lt;h2&gt;
  
  
  The tools
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;wapimaji-mcp&lt;/strong&gt; provides Kenya NDMA drought phase classifications across all 47 counties:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Tool: kenya_county_drought
# Input: county_name
# Output: current drought phase (1-5), affected population, area
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;bima-mcp&lt;/strong&gt; provides parametric risk scoring and insurance product matching:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Tool: parametric_crop_risk
# Input: county, crop_type, area_ha, coverage_amount
# Output: risk score, premium estimate, trigger conditions
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The agent workflow
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;I have 2 hectares of maize in Turkana County. How much will crop insurance cost?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="mf"&gt;1.&lt;/span&gt; &lt;span class="n"&gt;wapimaji_mcp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;kenya_county_drought&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;county&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Turkana&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="n"&gt;Phase&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Emergency&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;67&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;area&lt;/span&gt; &lt;span class="n"&gt;affected&lt;/span&gt;

&lt;span class="mf"&gt;2.&lt;/span&gt; &lt;span class="n"&gt;bima_mcp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parametric_crop_risk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
     &lt;span class="n"&gt;county&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Turkana&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
     &lt;span class="n"&gt;crop_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;maize&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="n"&gt;area_ha&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="n"&gt;coverage_amount&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50000&lt;/span&gt;
   &lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="n"&gt;Risk&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;HIGH&lt;/span&gt;
   &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="n"&gt;Estimated&lt;/span&gt; &lt;span class="n"&gt;premium&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;KES&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;season&lt;/span&gt;
   &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="n"&gt;Trigger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Phase&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;consecutive&lt;/span&gt; &lt;span class="n"&gt;weeks&lt;/span&gt;
   &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="n"&gt;Payout&lt;/span&gt; &lt;span class="n"&gt;timeline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt; &lt;span class="n"&gt;days&lt;/span&gt; &lt;span class="n"&gt;after&lt;/span&gt; &lt;span class="n"&gt;trigger&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why the combination works
&lt;/h2&gt;

&lt;p&gt;Neither tool alone answers the question. The drought data provides current conditions; the risk tool prices the forward-looking exposure. Together, they give a complete picture in a single agent session.&lt;/p&gt;

&lt;p&gt;The farmer gets: a current drought assessment, a premium quote, and the exact trigger conditions — without calling a broker, visiting an office, or waiting for a human intermediary.&lt;/p&gt;

&lt;p&gt;This is the practical argument for coordination infrastructure. The data exists. The tools exist. The value comes from connecting them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo data disclaimer
&lt;/h2&gt;

&lt;p&gt;Both tools use synthetic demo data. In production, these would connect to real NDMA APIs and accredited insurance product APIs. The architecture is production-ready; the data sources need to be swapped.&lt;/p&gt;

&lt;p&gt;Source code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/gabrielmahia/wapimaji-mcp" rel="noopener noreferrer"&gt;wapimaji-mcp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gabrielmahia/bima-mcp" rel="noopener noreferrer"&gt;bima-mcp&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>insurance</category>
      <category>mcp</category>
      <category>africa</category>
      <category>climate</category>
    </item>
    <item>
      <title>Building an Alternative Credit Score from M-PESA Behavioral Data</title>
      <dc:creator>Gabriel Mahia</dc:creator>
      <pubDate>Fri, 03 Jul 2026 10:00:00 +0000</pubDate>
      <link>https://dev.to/gabrielmahia/building-an-alternative-credit-score-from-m-pesa-behavioral-data-1bl1</link>
      <guid>https://dev.to/gabrielmahia/building-an-alternative-credit-score-from-m-pesa-behavioral-data-1bl1</guid>
      <description>&lt;p&gt;FICO was invented in 1956 and took five decades of credit card data to become the global standard. That data simply doesn't exist for most Kenyan adults. But something else does: M-PESA.&lt;/p&gt;

&lt;p&gt;35 million Kenyans use M-PESA. Every paybill payment, every savings deposit, every Fuliza loan — that's a behavioral financial record. The question &lt;code&gt;mkopo-mcp&lt;/code&gt; asks is: can you build a 300–850 credit score from it?&lt;/p&gt;

&lt;h2&gt;
  
  
  The Research Basis
&lt;/h2&gt;

&lt;p&gt;The core insight comes from two bodies of work:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Breza &amp;amp; Kinnan (2021):&lt;/strong&gt; Mobile money adoption in India measurably improved credit access for previously unbanked households. Transaction regularity was a stronger predictor of repayment than income level.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;World Bank Financial Inclusion Database (2022):&lt;/strong&gt; In Sub-Saharan Africa, 57% of adults who use mobile money have never had a formal bank account. That's the population FICO was never designed to serve.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Central Bank of Kenya Prudential Guidelines (2022):&lt;/strong&gt; CRBs in Kenya are required to report both positive and negative credit information. Fuliza (M-PESA overdraft) data is already flowing to TransUnion Kenya.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Score Model
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mkopo_mcp&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;alternative_credit_score&lt;/span&gt;

&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;alternative_credit_score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;monthly_income_kes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;45000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;mpesa_transactions_monthly&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;avg_transaction_kes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1850&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;paybill_payments_monthly&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;fuliza_usage&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;occasional&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;savings_behavior&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;regular_deposits&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;phone_tenure_years&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;3.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;months_of_history&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# → score: 647, tier: "FAIR", loan_capacity_kes: 85000
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The score is decomposed into four signals:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Signal&lt;/th&gt;
&lt;th&gt;Weight&lt;/th&gt;
&lt;th&gt;Proxy For&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Income regularity&lt;/td&gt;
&lt;td&gt;30%&lt;/td&gt;
&lt;td&gt;Capacity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Payment consistency&lt;/td&gt;
&lt;td&gt;25%&lt;/td&gt;
&lt;td&gt;Willingness&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Savings behavior&lt;/td&gt;
&lt;td&gt;25%&lt;/td&gt;
&lt;td&gt;Financial discipline&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tenure + history&lt;/td&gt;
&lt;td&gt;20%&lt;/td&gt;
&lt;td&gt;Stability&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Why Behavioral Signals Work
&lt;/h2&gt;

&lt;p&gt;The intuition: a person who pays their Nairobi Water paybill on time, every month, for 18 months is demonstrating financial discipline that's directly relevant to loan repayment. It's not income — it's behavior.&lt;/p&gt;

&lt;p&gt;This is structurally similar to how FICO evolved to include rent payment data (FICO 10T, 2020) and how Experian Boost works in the US — both extend credit scoring to non-traditional signals.&lt;/p&gt;

&lt;p&gt;The difference is that in Kenya, those signals are already flowing through one system (M-PESA), not scattered across utilities and landlords.&lt;/p&gt;

&lt;h2&gt;
  
  
  What mkopo-mcp Doesn't Do
&lt;/h2&gt;

&lt;p&gt;Trust integrity matters here: &lt;strong&gt;mkopo-mcp is DEMO infrastructure&lt;/strong&gt;. It does not connect to real M-PESA transaction data. It models how a score would be computed if such data were available.&lt;/p&gt;

&lt;p&gt;Production deployment requires:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;User consent for M-PESA transaction access (Safaricom API)&lt;/li&gt;
&lt;li&gt;CBK data protection compliance (Data Protection Act 2019)&lt;/li&gt;
&lt;li&gt;CRB registration for institutions submitting scores&lt;/li&gt;
&lt;li&gt;Actuary-validated model weights (these are illustrative)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The infrastructure exists. The regulatory and data access path is defined. mkopo-mcp demonstrates the model.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Impact Calculation
&lt;/h2&gt;

&lt;p&gt;If even 10% of Kenya's 30M credit-invisible adults could access microfinance products through alternative scoring:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;3M people with access to KES 50,000–200,000 productive loans&lt;/li&gt;
&lt;li&gt;At 2% monthly default rate (optimistic) → marginal NPL is manageable&lt;/li&gt;
&lt;li&gt;Kenya's MSME financing gap: approximately KES 1.1T (IFC, 2022)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's not an app. That's coordination infrastructure.&lt;/p&gt;






&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;mkopo-mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://github.com/gabrielmahia/mkopo-mcp" rel="noopener noreferrer"&gt;github.com/gabrielmahia/mkopo-mcp&lt;/a&gt; · MIT License&lt;/p&gt;

</description>
      <category>fintech</category>
      <category>africa</category>
      <category>python</category>
      <category>mcp</category>
    </item>
  </channel>
</rss>
