Daraja Agent Kit
Esc

    Loading search…

    Open-source kit for Safaricom Daraja

    Let your agent take M-Pesa.

    Agent Skills that write correct Daraja code, an MCP server and mpesa CLI that call it safely, plus libraries for Python agents, Node, the Vercel AI SDK and n8n.

    curl -LsSf https://raw.githubusercontent.com/Mr-Macharia/mpesa-daraja-skills-and-mcp/main/install.sh | sh

    Then run mpesa init. Sandbox by default.

    Works with Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, LangChain, OpenAI Agents SDK, Agno, Google ADK, CrewAI, Vercel AI SDK, n8n.

    22

    Agent Skills

    24

    MCP tools

    27

    Tutorial lessons

    5

    Coding agents

    Quick start

    Let your agent install it.

    Paste this into Claude Code, Codex, Cursor, Gemini CLI or any coding agent.

    Prompt for your agent
    Install the M-Pesa Daraja Agent Kit for me:
    1. Install the Agent Skills for yourself: npx skills add Mr-Macharia/mpesa-daraja-skills-and-mcp -a <your agent id>
       (agent ids: claude-code, codex, cursor, github-copilot, gemini-cli). Use -g if I want them in every project.
    2. Add the MCP server to yourself, named "mpesa", with the command: uvx mpesa-daraja-mcp
       It needs no keys in your config. If uv is missing, tell me how to install it first.
    3. Don't ask me for my Daraja keys. Tell me to run `uvx mpesa-daraja-mcp init` in my own terminal,
       which saves them privately, then to restart you.
    4. After I restart you, call mpesa_check_credentials and tell me if everything works.

    Or install it yourself:

    1. 1

      Install the skills

      npx skills add Mr-Macharia/mpesa-daraja-skills-and-mcp

      Needs Node.js 22.20 or later.

    2. 2

      Save your keys and add the server

      uvx mpesa-daraja-mcp init

      Run it in your own terminal. Keys never go into the chat.

    3. 3

      Check it works

      uvx mpesa-daraja-mcp status

      Lists missing settings and re-tests your keys.

    One kit, six ways in

    Wherever your agent lives, M‑Pesa goes too.

    Every surface shares the same guardrails: sandbox first, idempotent money moves, no secrets in chat.

    claude-code · your-django-app

    you › Add M-Pesa checkout to my Django orders

    ● skill loaded: daraja-checkout

    ● order saved as pending before the STK Push

    ● callback matched on CheckoutRequestID

    ● STK Query when no callback arrives

    ● amount checked before marking paid

    ✓ Checkout written to Daraja's rules.

    $ npx skills add Mr-Macharia/mpesa-daraja-skills-and-mcpBrowse all 22 skills
    What to ask your agent

    Plain words in. Correct Daraja out.

    • Add M-Pesa checkout to my Django order flow, with a callback that marks orders paid.Skills
    • A customer says they paid. Did receipt TJK7Q2X9LM go through?MCP
    • Build a B2C payout job for driver earnings that never pays twice.Skills
    • My STK push returns 400.002.02. What's wrong with this request?Skills
    • Pull yesterday's C2B transactions and match them against my invoices.Both
    • Set up a monthly KES 500 standing order for this subscriber.Both
    Safety

    Money tools that don't guess.

    Every result is SUCCESS, FAILED or UNKNOWN. Payouts can be capped, limited to known recipients, or switched off entirely.

    Sandbox by default

    In production, money tools refuse to run until you allow live money movement.

    Idempotency keys

    Each money request is stored under a key. Repeating it returns the stored outcome, so a retry never pays twice.

    Accepted is not paid

    Only a callback or a status query can produce SUCCESS.

    No secrets in chat

    Tokens and secrets never appear in tool output, and keys never go in agent config.

    The life of one paymentResponseCode "0" means accepted, never paid
    1. 1Request sentmpesa_stk_push
    2. 2ACCEPTEDtaken, not paid
    3. 3Customer PINon their phone
    4. 4Callback or querythe only proof
    5. 5SUCCESSreceipt TJK7Q2X9LM

    No answer in time? The result is UNKNOWN, and the kit queries before it ever resends, reusing the same idempotency_key.

    Who it helps

    From the developer to the chama treasurer.

    Developers

    Correct STK checkout, payouts and callback handlers, with retries that never pay twice.

    Shops and SaaS

    Checkout in the app, Dynamic QR at the counter, subscriptions through Ratiba standing orders.

    Finance and operations

    Reconcile C2B payments against invoices, check balances, run reversals from chat.

    Learners

    Sandbox experiments with real responses, and docs that explain why each rule exists.

    FAQ

    Questions, answered.

    Do I need a Safaricom account?

    A free Daraja developer account and a sandbox app, for its Consumer Key and Secret. Sandbox shortcode 174379 and its passkey work out of the box for STK Push.

    Will it charge real money?

    Only if you set DARAJA_ENV=production with live keys and DARAJA_ALLOW_LIVE_MONEY_MOVEMENT=true.

    Why didn't I get a receipt?

    Safaricom sends the receipt to your callback URL, so set DARAJA_CALLBACK_BASE_URL to a public HTTPS address such as an ngrok tunnel. Without one, mpesa_stk_push_and_wait still reports the outcome through STK Query, just without the receipt number.

    My agent says “Connection closed”.

    Run mpesa status. It lists missing settings and re-tests your keys. Then restart the agent.

    Your first sandbox payment is a few commands away.

    Stuck on something the docs don't cover? Ask.