daraja-mcp
This server acts as an MCP client for Safaricom's M-Pesa Daraja 3.0 API, enabling AI models to initiate, monitor, and manage financial operations — including a built-in simulator so you can test everything without a Safaricom account.
Payments (Customer → Business)
stk_push/stk_push_and_wait– Send an STK push prompt to a customer (with or without waiting for the result).stk_query– Check STK push status.ratiba_create/ratiba_create_and_wait– Create recurring standing orders.generate_qr– Generate dynamic M-Pesa QR codes.
Disbursements (Business → Customer/Business)
b2c_payment/b2c_payment_and_wait– Send money to customers (refunds, salaries, etc.).b2b_payment– Pay other businesses (PayBills, tills, working accounts).tax_remittance– Remit tax to KRA via PRN.business_to_pochi– Pay a Pochi la Biashara number.
Treasury / Account Management
account_balance– Query business account balance (via callback).transaction_status– Check any past transaction by receipt or conversation ID.reversal– Reverse a C2B transaction.
C2B Management
c2b_register_urls– Register validation/confirmation URLs.c2b_simulate– Simulate customer payment (sandbox/simulator only).pull_register/pull_transactions– Register for Pull API and fetch missed transactions.
Identity & Fraud Prevention
check_sim_swap– Check last SIM swap date for a number.check_age_on_network– Get number's registration age (fraud risk).validate_identity– Verify phone number against national ID.query_org_info– Look up name/tariff for PayBill or till.
Diagnostics
list_callbacks/get_callback– View recent callbacks or retrieve by correlation ID.server_health– Check mode, credentials, and callback receiver status.
Developer/Testing Features
Simulator mode by default – No Safaricom credentials needed; special amounts (e.g., 1032 = cancelled, 9999 = upstream error) simulate deterministic failures.
Built-in callback receiver with path secret support and source IP verification against Safaricom ranges (cannot be disabled in production).
Direct client and simulator export for integration.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@daraja-mcpSend an STK push to 254712345678 for 500 KES and wait for the receipt"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
daraja-mcp
An MCP server for the Safaricom M-Pesa Daraja 3.0 API.
Covers the full product surface including M-Pesa Ratiba, verifies the source of inbound callbacks, and ships a simulator so you can run every tool without a Safaricom account.
npx daraja-mcpThat works on a machine that has never heard of Safaricom. No credentials, no
sandbox app, no tunnel. It starts a local fake Daraja and points the server at
it, so you can call stk_push_and_wait and watch a payment settle end to end
before you decide whether this is worth your time.
Why another one
There are several M-Pesa MCP servers already. Most wrap POST /stkpush and
stop. The three things that make Daraja genuinely hard to work with are:
The result does not come back in the response. You initiate a payment, get
an acknowledgement, and the actual outcome arrives on a webhook up to a minute
later. A tool that returns the acknowledgement has told the model nothing. So
this server runs a callback receiver and offers *_and_wait tools that block
until the real outcome arrives and return the receipt number.
Callbacks are unsigned. Safaricom does not sign callback bodies. The only thing distinguishing a genuine payment result from a forged one is the source address, which means an open callback endpoint lets anyone mark an unpaid order as paid. This server verifies inbound callbacks against Safaricom's published egress ranges, supports an unguessable path secret, and refuses to disable verification in production.
You cannot test any of it without an account. Daraja requires credentials and a publicly reachable HTTPS callback URL before the first request works. The bundled simulator speaks the real endpoint paths, returns the real payload shapes, and pushes callbacks the way Safaricom does, so the test suite runs in CI with no secrets and you can evaluate the server in under a minute.
Related MCP server: Daraja API MCP Server
Install
Add to your MCP client config:
{
"mcpServers": {
"daraja": {
"command": "npx",
"args": ["-y", "daraja-mcp"]
}
}
}That runs in simulator mode. To talk to the real sandbox, add credentials:
{
"mcpServers": {
"daraja": {
"command": "npx",
"args": ["-y", "daraja-mcp"],
"env": {
"DARAJA_CONSUMER_KEY": "your-key",
"DARAJA_CONSUMER_SECRET": "your-secret",
"DARAJA_SHORTCODE": "174379",
"DARAJA_PASSKEY": "your-passkey",
"DARAJA_CALLBACK_PUBLIC_URL": "https://your-tunnel.ngrok.io"
}
}
}
}Client-specific instructions: docs/clients.md.
Tools
Payments
Tool | What it does |
| Send a payment prompt. Returns an acknowledgement only. |
| Send a prompt and wait for the customer. Returns the receipt. |
| Check the status of a previous prompt. |
| Create a standing order for recurring collection. |
| Create one and wait for the customer to approve. |
| Generate a dynamic QR code. |
Disbursement
Tool | What it does |
| Pay a customer: refunds, withdrawals, salaries. |
| Same, but returns the settled result. |
| Pay a PayBill, a till, or top up a B2C working account. |
| Remit tax to KRA against a PRN. |
| Pay a Pochi la Biashara number. |
Treasury
Tool | What it does |
| Query your business account balance. |
| Look up any past transaction. |
| Reverse a transaction paid into your shortcode. |
Customer to business
Tool | What it does |
| Register validation and confirmation URLs. |
| Simulate a customer payment. Sandbox only. |
| Register for the Pull Transactions API. |
| Fetch C2B transactions for a window. |
Identity and fraud (new in Daraja 3.0)
Tool | What it does |
| When was this number last SIM-swapped? |
| When was this number first registered? |
| Is this number registered to this national ID? |
| What business owns this shortcode, and at what tariff? |
Those four are worth more than they look. Checking for a recent SIM swap before
disbursing to an unfamiliar number is a cheap control against SIM-swap fraud,
and query_org_info catches a fat-fingered shortcode before the money leaves.
Diagnostics
Tool | What it does |
| Recent callbacks, newest first. |
| Full payload for a correlation id. |
| Mode, configured credentials, receiver status. |
Start with server_health when something is not working.
Testing without a Safaricom account
Simulator mode is the default when no credentials are set. Failure paths are driven by the amount, so you can exercise every branch deterministically:
Amount | What happens |
anything normal | Success, with a receipt number |
| Insufficient funds |
| Cancelled by user |
| Timeout, customer unreachable |
| Wrong PIN |
| Upstream 500, to exercise retry handling |
So stk_push_and_wait with amount 1032 gives you a realistic cancelled
payment, including the detail that failure callbacks carry no
CallbackMetadata at all. Code that reads the receipt number unconditionally
breaks there, which is exactly what you want to find locally.
Going live
Read docs/going-live.md before pointing this at production. The short version:
Set
DARAJA_MODE=productionand real credentials.Set
DARAJA_CALLBACK_PUBLIC_URLto a public HTTPS endpoint.Leave source verification on. It is on by default and the server refuses to let you disable it in production.
Set
DARAJA_CALLBACK_PATH_SECRETto a random string.
Ratiba additionally requires a signed commercial agreement with Safaricom before it works outside the sandbox.
Configuration
Variable | Purpose |
|
|
| From your Daraja app |
| From your Daraja app |
| PayBill or till number |
| Lipa na M-Pesa passkey, for STK push |
| For B2C, B2B, reversals, balance |
| Encrypted initiator password |
| Public URL Safaricom can reach |
| Local listener port, default |
| Unguessable path segment |
| Override allowed source ranges |
| Skip the callback listener entirely |
Notes on Daraja's own inconsistencies
These are reproduced deliberately rather than tidied up, because Daraja rejects the corrected forms:
B2C sends
InitiatorName; B2B and the treasury APIs sendInitiator.RecieverIdentifierTypeis misspelled in the specification.B2C expects
Occassion; transaction status expectsOccasion.Ratiba's published sample says
StandingOrderNameNamewhile its parameter table saysStandingOrderName. Both are sent.Ratiba's synchronous response uses
ResponseHeaderand code200; its callback usesresponseHeaderand code0. Different casing, different code space, same product.STK
ResultCodeis numeric; most other products send it as a string.
The timestamp is rendered in East Africa Time rather than UTC. Using UTC backdates the request by three hours and Daraja rejects it as expired, which is the single most common STK push bug.
Using the pieces directly
The client, simulator, and callback receiver are exported independently if you want them without MCP:
import { DarajaClient, DarajaSimulator, loadConfig } from 'daraja-mcp';Development
npm install
npm test # 507 tests, no credentials needed
npm run test:coverage # with a coverage report
npm run build
npm run verify # typecheck, test, build, and an end-to-end MCP checknpm run verify is the full gate. It drives the built CLI over stdio MCP
through a payment, a cancellation, and a standing order against the simulator,
so it needs no Safaricom credentials.
Coverage sits at about 98% of lines, with thresholds enforced by the test run
so a regression fails rather than passing quietly. The badge is generated
locally with npm run coverage:badge, since this repository does not run CI.
The docs site is served from the gh-pages branch. To update it, edit
site/index.html on main and run npm run docs:publish.
Contributing
Bug reports and pull requests are welcome. See CONTRIBUTING.md for how to get set up and what makes a change likely to be merged.
The most useful thing you can report is a Daraja discrepancy: a case where the real API behaves differently from what this server assumes. Those are the ones the simulator cannot catch on its own. There is an issue template for it.
Everything here derives from Safaricom's public documentation. Please do not contribute code or payloads taken from an employer's or client's private integration.
Security
Callbacks are unsigned, so a forged one that gets accepted is a real vulnerability. Report privately rather than in a public issue: see SECURITY.md.
Disclaimer
Not affiliated with or endorsed by Safaricom PLC. M-PESA and Daraja are their trademarks. Built from the public Daraja documentation.
License
MIT
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Flicense-qualityDmaintenanceA Model Context Protocol server that integrates AI applications with Safaricom's Daraja API, enabling AI-driven financial transactions and automation through M-Pesa services.Last updated14
- Alicense-qualityDmaintenanceProvides AI assistants with access to comprehensive Safaricom Daraja API documentation for all 22 M-Pesa APIs through searchable tools, enabling developers to query payment processing, transaction management, and business operations documentation.Last updated15MIT
- AlicenseAqualityCmaintenanceMCP server for East African fintech APIs — trigger M-Pesa STK Push payments, check transaction status, send SMS to 20+ African networks, and top up airtime via Africa's Talking.Last updated55MIT

PayLink MCP Serverofficial
Flicense-qualityDmaintenanceOpen-source MCP server that streamlines payment integration for AI agents and financial apps in Africa, providing unified tools for providers like M-Pesa.Last updated1
Related MCP Connectors
Kenya payments for AI agents — M-Pesa via Flutterwave. Never holds funds.
Tanzania payments for AI agents — M-Pesa / Tigo Pesa via Flutterwave. Never holds funds.
Hosted MCP endpoint with realistic fake data for prototyping agents. 12 tools, no setup.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/parseen254/daraja-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server