DEV Community

Gabriel Mahia
Gabriel Mahia

Posted on • Originally published at gabrielmahia.github.io

How I Built an MCP Server for M-PESA — and Why It Matters for East Africa

Kenya's M-PESA processes $314 billion annually. 35 million users. And until recently, there was no way for an AI agent to interact with it natively.

That changed when I built mpesa-mcp — a Model Context Protocol server that wraps the Daraja API and makes it directly available to Claude, GPT-4, and Gemini.

What is MCP?

Model Context Protocol (MCP) is Anthropic's open standard for connecting AI agents to external tools and data sources. Think of it like REST, but for AI agents — instead of an LLM hallucinating what an API might return, it calls real tools with real data.

An MCP server exposes tools. An AI agent calls those tools. The agent never has to understand the underlying API — it just asks "what tools do you have?" and gets structured results back.

The Problem with M-PESA Integration

M-PESA's Daraja API is well-documented but non-trivial to integrate:

  • OAuth 2.0 token flow with 1-hour expiry
  • Request body for STK push includes a base64-encoded password derived from shortcode + passkey + timestamp — regenerated every request
  • Different base URLs for sandbox vs production
  • Different authentication flows for STK push, B2C, balance query, transaction status
  • Error codes are numeric strings, not HTTP status codes

For every developer building an AI assistant on M-PESA, this was ~2 days of integration work before writing a single line of product logic. And every team building their own integration meant every team making the same mistakes with the passkey encoding.

The Solution: mpesa-mcp

pip install mpesa-mcp
claude mcp add mpesa -- mpesa-mcp
Enter fullscreen mode Exit fullscreen mode

That's it. Your Claude instance can now:

  • Initiate STK push payments (Lipa Na M-PESA)
  • Execute B2C disbursements
  • Query account balances
  • Check transaction status
  • Register C2B callback URLs

Here's what a tool call looks like from inside the server:

def mcp_call_tool(name: str, arguments: dict) -> dict:
    if name == "mpesa_stk_push":
        token = get_access_token()  # handles OAuth internally
        password = generate_password(shortcode, passkey)  # base64 + timestamp
        return initiate_stk_push(
            token=token,
            phone=arguments["phone_number"],
            amount=arguments["amount"],
            account_ref=arguments.get("account_reference", "Payment")
        )
Enter fullscreen mode Exit fullscreen mode

The MCP server handles the OAuth dance, password generation, and error normalization. The AI agent just says "initiate an M-PESA payment of 100 to 0722000000" and gets a structured result back.

Why "First African Payment API in MCP"

When I shipped mpesa-mcp in 2024, there were hundreds of MCP servers for AWS, GitHub, Stripe, Slack — every major Western tech API. There were zero for African financial infrastructure.

That gap matters. M-PESA isn't just Kenya's payment system — it's the model for mobile money globally. It's processed more transactions than PayPal in some quarters. It operates in Kenya, Tanzania, Uganda, Rwanda, Mozambique, Lesotho, Ghana, and Egypt. And it had no AI agent integration.

mpesa-mcp makes M-PESA a first-class citizen in the MCP ecosystem.

Results

  • v0.1.9 on PyPI: pip install mpesa-mcp
  • 400+ downloads across 12 countries — without any marketing
  • PR #7395 on awesome-mcp-servers
  • Part of a 110+ tool East Africa AI portfolio

What's Next

mpesa-mcp v2.0 will add Swahili-native tool descriptions — so AI agents receiving instructions in Kiswahili can call M-PESA tools correctly without any translation step. This is part of the LINGUA Africa grant application targeting Swahili model fine-tuning.

The repo is MIT licensed and open for contributions.

GitHub: gabrielmahia/mpesa-mcp

PyPI: pypi.org/project/mpesa-mcp

Portfolio: gabrielmahia.github.io

Top comments (0)