momo-mcp
Provides tools for Mobile Money payments through Orange Money, enabling AI agents to request payments, disburse funds, and check transaction statuses in Francophone West Africa.
Click on "Deploy 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., "@momo-mcpRequest payment of 5000 FCFA from +22996123456"
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.
momo-mcp
FR — Un serveur MCP pour Mobile Money en Afrique de l'Ouest francophone. Une seule intégration pour permettre à un agent IA de faire des paiements Mobile Money — sans jongler entre les API de MTN MoMo, Moov Africa et Orange Money.
EN — An MCP server for Mobile Money in Francophone West Africa. One integration that lets an AI agent make Mobile Money payments — without juggling the MTN MoMo, Moov Africa, and Orange Money APIs.
FR — Aujourd'hui : MTN MoMo, multi-pays, sandbox et production. L'architecture est prête à accueillir Moov Africa et Orange Money sans réécrire le serveur.
EN — Today: MTN MoMo, multi-country, sandbox and production. The architecture is ready to host Moov Africa and Orange Money without rewriting the server.
⚠️ FR — Statut : à valider avant tout usage réel. Le serveur est testé (35 tests) et couvre la gestion d'erreurs, le retry et le multi-pays. Il n'a pas encore été audité ni utilisé avec de vrais fonds. En production, valide de bout en bout sur un compte marchand MTN avant de l'exposer.
⚠️ EN — Status: validate before any real use. The server is tested (35 tests) and covers error handling, retries, and multi-country routing. It has not been audited or used with real funds yet. In production, validate end-to-end on an MTN merchant account before exposing it.
Pourquoi / Why
FR — La plupart des outils IA génériques (Stripe, PayPal...) ne couvrent pas le Mobile Money, qui reste le moyen de paiement dominant en Afrique de l'Ouest. Les rares intégrations existantes ciblent surtout l'Afrique anglophone/de l'Est. momo-mcp comble ce vide pour les développeurs qui construisent des agents IA (assistants d'achat, bots de paiement, outils de facturation) sur ce marché.
EN — Most generic AI payment tools (Stripe, PayPal...) don't cover Mobile Money, still the dominant payment method in West Africa. The few existing integrations mostly target anglophone/East Africa. momo-mcp fills that gap for developers building AI agents (shopping assistants, payment bots, invoicing tools) in this market.
Related MCP server: M-Pesa MCP Server
Outils exposés / Tools
FR/EN — Chaque outil renvoie un dict JSON. Les succès contiennent ok: true ; les échecs ok: false + un objet error (voir Erreurs).
Outil / Tool | FR | EN |
| Demande un paiement à un client (Request-to-Pay). Asynchrone : renvoie | Request a payment from a customer (Request-to-Pay). Async: returns |
| Envoie de l'argent à un utilisateur (remboursement, salaire, payout). Sortie de fonds — annoté | Send money to a user (refund, salary, payout). Fund outflow — annotated |
| Statut final d'un paiement ou transfert. Utilise | Final status of a payment or transfer. Uses |
| Vérifie qu'un numéro a un compte Mobile Money actif avant d'y envoyer des fonds. | Check a number has an active Mobile Money account before sending funds. |
Cycle d'un paiement / Payment flow
flowchart TD
A["request_payment(phone_number, amount, currency, external_id, country)"] --> B["status: PENDING + reference_id"]
B --> C["Customer confirms with PIN on their phone"]
C --> D["check_payment_status(reference_id, kind=collection, country)"]
D --> E{"status ?"}
E -->|SUCCESSFUL| F["Settled - financial_transaction_id"]
E -->|FAILED| G["Failed - reason"]
E -->|PENDING| DFR — request_payment est asynchrone : le statut reste PENDING tant que le client n'a pas confirmé. Interroge check_payment_status périodiquement (quelques secondes à quelques minutes).
EN — request_payment is async: status stays PENDING until the customer confirms. Poll check_payment_status (seconds to minutes).
Pays supportés / Supported countries
FR — Le paramètre country de chaque outil sélectionne la config MTN (header X-Target-Environment, devise, format de numéro). En sandbox, utilise benin (ou n'importe quel pays avec la devise EUR). En production, la devise locale du pays est requise.
EN — The country parameter on every tool selects the MTN config (X-Target-Environment header, currency, number format). In sandbox use benin (or any country with EUR). In production the country's local currency is required.
| X-Target-Environment | Devise / Currency | Indicatif / Code | Exemple / Example |
|
| XOF | 229 |
|
|
| XOF | 225 |
|
|
| XAF | 237 |
|
|
| XAF | 242 |
|
|
| GNF | 224 |
|
|
| GHS | 233 |
|
|
| LRD | 231 |
|
|
| UGX | 256 |
|
|
| ZMW | 260 |
|
|
| RWF | 250 |
|
|
| ZAR | 27 |
|
|
| SZL | 268 |
|
Alias acceptés / Accepted aliases : bj→benin, ci/cote_d_ivoire/côte d'ivoire→ivory_coast, cm→cameroon, congo_brazzaville→congo, guinea_conakry→guinea, swaziland→eswatini. Insensible à la casse, aux accents et aux espaces.
Installation
git clone https://github.com/Tahsine/momo-mcp.git
cd momo-mcp
python -m venv .venv && source .venv/bin/activate
pip install -e .Configuration (sandbox MTN MoMo)
FR
Crée un compte gratuit sur momodeveloper.mtn.com et abonne-toi aux produits Collection et Disbursement → récupère les deux clés d'abonnement.
Provisionne ton API user + API key (une seule fois) :
python scripts/provision_mtn.py --subscription-key TA_CLE_COLLECTIONCopie
.env.examplevers.envet renseigne les valeurs. Voir le détail des variables dans.env.example.
EN
Create a free account at momodeveloper.mtn.com, subscribe to Collection and Disbursement, and grab both subscription keys.
Provision your API user + API key (once):
python scripts/provision_mtn.py --subscription-key YOUR_COLLECTION_KEYCopy
.env.exampleto.envand fill in the values. See.env.examplefor every variable.
Variable | Rôle / Purpose |
| Clé produit Collection (paiements entrants). |
| Clé produit Disbursement (paiements sortants). |
| Identifiants API (sandbox : via |
|
|
|
|
| (Optionnel) Messages prédéfinis autorisés comme |
| Longueur max d'un |
| Plafond par appel de |
| Plafond quotidien (UTC) des sorties de fonds, persisté en SQLite. Vide/invalide/ |
| Fichier du compteur quotidien (défaut |
| Échappatoire : accepte des sorties sans plafond en production. Valeur exacte |
Utilisation avec un client MCP / Using an MCP client
Claude Code
claude mcp add momo-mcp -- python -m momo_mcp.serverInspecteur MCP / MCP Inspector
npx @modelcontextprotocol/inspector python -m momo_mcp.serverDocker — le serveur parle le protocole MCP sur stdin/stdout :
docker build -t momo-mcp .
docker run -i --env-file .env momo-mcpRéférence des outils / Tool reference
request_payment
Param | Requis | Description |
| oui | MSISDN du payeur, format international sans |
| oui | Montant en chaîne (ex : |
| oui | Devise du pays (XOF, XAF...) ou |
| oui | Référence interne à ton système (ex : n° de commande). |
| non | Message affiché au payeur. |
| non | Note interne liée à la transaction. |
| non |
|
| non | Pays MTN (défaut |
disburse_payment
Mêmes paramètres (message au lieu de payer_message/payee_note) — envoie des fonds sans confirmation PIN.
check_payment_status
Param | Requis | Description |
| oui | Identifiant retourné par |
| non |
|
| non | Pays d'origine de la transaction (requis en production). |
validate_account
Param | Requis | Description |
| oui | MSISDN à vérifier. |
| non | Pays MTN (défaut |
Erreurs / Errors
FR — Aucun outil ne lève d'exception vers l'agent. Toute erreur devient :
{
"ok": false,
"error": {
"code": "devise_invalide",
"message": "Devise non supportée pour ce compte...",
"message_en": "Currency not supported for this account.",
"retryable": false,
"http_status": 500,
"detail": "INVALID_CURRENCY"
}
}EN — No tool raises an exception to the agent. Every error becomes the dict above. Check retryable: if true, retrying the same call may succeed.
Codes principaux / Main codes (extrait — voir src/momo_mcp/errors.py)
| Retryable | Cause |
| non | Paramètre invalide (numéro, montant, devise, |
| non |
|
| non | Pas de compte Mobile Money actif pour ce numéro. |
| non | Solde payeur insuffisant. |
| non | Devise non supportée (utilise la devise du pays). |
| non |
|
| non | Clé d'abonnement ou identifiants API invalides. |
| oui | Limite de débit MTN atteinte. |
| oui | MTN injoignable / délai dépassé. |
| oui | Erreur temporaire côté MTN. |
| non | Erreur inattendue du serveur |
Comportement de retry / Retry behaviour — Le client réessaie automatiquement une fois les erreurs réseau, 5xx et les tokens expirés (401), en réutilisant le même X-Reference-Id (idempotent côté MTN). Les erreurs métier (4xx, code MTN) ne sont jamais réessayées automatiquement.
Sécurité / Security
FR — Un serveur MCP qui déplace de l'argent expose des primitives à un LLM. Garde-fous intégrés :
Sortie de fonds signalée.
disburse_paymentporte l'annotation MCPdestructiveHint: true(etopenWorldHint: true) ; les clients qui le gèrent peuvent exiger une confirmation humaine.check_payment_statusetvalidate_accountsontreadOnlyHint: true.Plafonds + barrière de production.
MOMO_MAX_DISBURSEMENT(par appel) etMOMO_MAX_DAILY_DISBURSEMENT(par jour UTC) bornent les sorties ; dépassement → erreurplafond_depasse(non réessayable). SiMTN_TARGET_ENVIRONMENT != "sandbox"et qu'aucun plafond n'est défini, le serveur refuse de démarrer — sauf échappatoire expliciteMOMO_ALLOW_UNCAPPED_DISBURSEMENT=true. Le compteur quotidien est persisté en SQLite (réservation atomique) : il survit aux redémarrages et se partage entre instances ; une réservation est libérée si l'appel MTN échoue.Canal
payer_messagerestreint. Le message affiché sur le téléphone du payeur n'est jamais du texte libre : il doit être vide ou l'un des messages prédéfinis (MOMO_PAYER_MESSAGES), sous plafond de longueur. Cela ferme un vecteur de phishing (un agent rédigeant le texte que la victime lit avant de saisir son PIN).Erreurs structurées. Aucune stack trace vers le modèle ; toute erreur est un objet
{code, message, retryable}exploitable sans fuite d'information.Pas de fuite d'identifiants. Les clés vivent dans
.env(non commité) ; rien n'est journalisé en clair.
EN — A money-moving MCP server hands primitives to an LLM. Built-in guardrails:
Outflow is flagged.
disburse_paymentcarries the MCPdestructiveHint: trueannotation (plusopenWorldHint: true); clients that honour it can require human confirmation.check_payment_statusandvalidate_accountarereadOnlyHint: true.Caps + production barrier.
MOMO_MAX_DISBURSEMENT(per call) andMOMO_MAX_DAILY_DISBURSEMENT(per UTC day) bound outflows; exceeding them returns aplafond_depasseerror (non-retryable). IfMTN_TARGET_ENVIRONMENT != "sandbox"and no cap is set, the server refuses to start — unless the explicit escape hatchMOMO_ALLOW_UNCAPPED_DISBURSEMENT=trueis set. The daily counter is persisted in SQLite (atomic reservation): it survives restarts and is shared across instances; a reservation is released if the MTN call fails.Restricted
payer_messagechannel. The message shown on the payer's phone is never free text: it must be empty or one of the configuredMOMO_PAYER_MESSAGES, under a length cap. This closes a phishing vector (an agent writing what the victim reads before entering their PIN).Structured errors. No stack traces to the model; every error is a
{code, message, retryable}object.No credential leakage. Keys live in
.env(not committed); nothing sensitive is logged.
Voir / see SECURITY.md.
Mise en production / Production checklist
FR
Passer par le Partner Portal MTN de ton pays : KYC + compte marchand local requis pour la production.
Récupérer les clés d'abonnement production sur
momoapi.mtn.comet les identifiants API du pays.MTN_TARGET_ENVIRONMENT≠sandbox,MTN_BASE_URL=https://proxy.momoapi.mtn.com.Définir
MOMO_MAX_DISBURSEMENTetMOMO_MAX_DAILY_DISBURSEMENT(obligatoires en production), et monter un volume surMOMO_STATE_DBen Docker.Renseigner un
providerCallbackHostréel :scripts/provision_mtn.pyutilisehttps://example.compar défaut (à adapter).Passer
external_idunique par transaction (sinonreference_dupliquee).Valider le parcours complet sur un petit montant réel avant d'exposer l'agent.
EN
Go through the country MTN Partner Portal: KYC + local merchant account are required for production.
Get production subscription keys on
momoapi.mtn.comand the country API credentials.Set
MTN_TARGET_ENVIRONMENT≠sandboxandMTN_BASE_URL=https://proxy.momoapi.mtn.com.Set
MOMO_MAX_DISBURSEMENTandMOMO_MAX_DAILY_DISBURSEMENT(mandatory in production), and mount a volume onMOMO_STATE_DBin Docker.Provide a real
providerCallbackHost:scripts/provision_mtn.pydefaults tohttps://example.com(change it).Use a unique
external_idper transaction (otherwisereference_dupliquee).Run the full flow on a small real amount before exposing the agent.
Développement / Development
pip install -e ".[dev]"
ruff check . # lint
pytest # 66 tests, aucun réseau réel (respx mocke MTN)FR — Les tests n'appellent jamais MTN : respx intercepte les requêtes HTTP. Le build Docker est validé en CI (Python 3.10 / 3.12 + build image). Un test « comme un agent » (vrai client MCP, appels sandbox réels) vit dans docs/agent-test/ — hors CI.
EN — Tests never call MTN: respx intercepts HTTP. The Docker build is validated in CI (Python 3.10 / 3.12 + image build). An agent smoke test (real MCP client, real sandbox calls) lives in docs/agent-test/ — not run in CI.
Feuille de route / Roadmap
MTN MoMo (Collection + Disbursement) — sandbox, multi-pays
Gestion d'erreurs structurée + retry idempotent
Tests, CI, image Docker
MTN MoMo — validation production
Migration
mcpv2 (FastMCP → MCPServer)Moov Africa
Orange Money
Webhook optionnel (éviter le polling de
check_payment_status)
Contact
FR — Construit par Tahsine (Borrelle Dev) à Cotonou, Bénin. Questions, retours, intégration sur-mesure (Moov, Orange, autre marché) : ouvre une issue ou écris-moi sur LinkedIn / GitHub.
EN — Built by Tahsine (Borrelle Dev) in Cotonou, Benin. Questions, feedback, custom integrations (Moov, Orange, other markets): open an issue or reach me on LinkedIn / GitHub.
Licence / License
MIT — voir / see LICENSE.
This server cannot be deployed
Maintenance
Related MCP Connectors
MCP server for building and testing AI agents with multi-model experimentation and insights.
MCP server for your apps' tools and custom tools, plus hosted AI agents and approval-gated workflows
The Mercado Pago MCP Server implements the Model Context Protocol to provide AI agents and LLMs with access to Mercado Pago's APIs and tools within compatible development environments. It acts as an intermediary that translates Mercado Pago resources into executable functions (tools) that AI applications can invoke to perform actions and automate flows. The server simplifies integration, enables using documentation to implement or improve code, and optimizes operations through natural language interactions without manual implementations.
MCP server connecting AI agents to 100+ apps (Gmail, Slack, Notion, GitHub) via one-click OAuth.
Related MCP Servers
FlicenseNot gradedqualityDmaintenanceOpen-source MCP server that streamlines payment integration for AI agents and financial apps in Africa, providing unified tools for providers like M-Pesa.1-- FlicenseNot gradedqualityDmaintenanceAn experimental MCP server that lets AI agents interact with guarded payment workflows through typed tools, enabling safe agent-assisted payments with M-Pesa and mock Airtel Money.2-

cinetpay-mcpofficial
AlicenseAqualityDmaintenanceMCP server that connects AI assistants to the CinetPay API for mobile money payments across Africa, enabling balance checks, payment initialization, transfers, and more.77 npmMIT- AlicenseNot gradedqualityBmaintenanceA remote MCP server that lets any AI agent accept payments in Rwanda via MTN Mobile Money, Airtel Money, and cards through Flutterwave's hosted checkout.MIT