Skip to main content
Glama
MifosX Self Service MCP

MifosX Self Service MCP

Official
by openMF

MifosX Self Service MCP

MifosX Self Service MCP is a Model Context Protocol (MCP) server built using FastMCP (Python). It exposes a set of AI-callable tools that allow MCP-compatible clients (such as Claude Desktop or DeepChat) to securely interact with the Apache Fineract / MifosX Self-Service APIs.

This project enables AI-driven banking workflows such as authentication, account access, beneficiary management, loans, savings, and transfers — while keeping all sensitive logic on the server side.

Features

  • Register new self-service users.

  • Confirm user registration.

  • User login and authentication.

  • Manage client information.

  • Manage beneficiaries (add, list, update, delete).

  • View client accounts and transactions.

  • Manage loans (view products, applications, transactions, charges).

  • Manage savings accounts (products, applications, transactions, charges).

  • Manage guarantors for loans.

  • Manage share accounts and products.

  • Read account statements and spending insights (statement, summary, recurring payments).

  • Register for push notifications.

  • Perform third-party account transfers.

Related MCP server: Griffin MCP server

Architecture

The MCP server acts as a secure bridge between your AI client and the Mifos/Fineract backend.

graph LR
    A[AI Client] -- MCP Protocol --> B[FastMCP Server]
    B -- REST API --> C[MifosX / Fineract]
    C -- Data --> B
    B -- Context --> A

Project Structure

The codebase is organized into a modular, maintainable structure:

mcp-mifosx-self-service/
│
├── main.py              # MCP server entry point
├── mcp_app.py           # FastMCP app initialization
│
├── config/
│   └── config.py        # Environment-based configuration
│
├── routers/             # MCP tools grouped by domain
│   ├── auth_tools.py        # User registration & authentication
│   ├── client_tools.py      # Client information & accounts
│   ├── beneficiary_tools.py # Beneficiary management
│   ├── transfer_tools.py   # Third-party transfers
│   ├── loan_tools.py        # Loan products & accounts
│   ├── savings_tools.py     # Savings accounts & products
│   ├── statement_tools.py   # Statements, spending summary, recurring payments
│   ├── guarantor_tools.py  # Loan guarantor management
│   ├── shares_tools.py     # Share accounts & products
│   └── notification_tools.py # Push notification registration
│
├── schemas/             # Pydantic request/response models
│   ├── registration.py
│   ├── authentication.py
│   ├── confirm.py
│   ├── beneficiary.py
│   └── transfer.py
│
├── utils/               # Shared helpers
│   ├── http.py          # Centralized HTTP client
│   └── auth.py          # Auth helpers (Basic Auth)
│
├── resources/           # MCP resources (context & docs)
│   ├── overview.py
│   ├── endpoints.py
│   └── workflows.py
│
├── requirements.txt
├── Dockerfile
├── docker-compose.yml
└── README.md

Installation

  1. Clone the repository:

    git clone https://github.com/openMF/mcp-mifosx-self-service.git
    cd mcp-mifosx-self-service
  2. Create and activate a virtual environment (recommended):

    python3 -m venv venv
    source venv/bin/activate  # On Windows: venv\Scripts\activate
  3. Install the required dependencies:

    pip install -r requirements.txt

Configuration

The application connects to a Fineract API. Use environment variables (or a .env file) for customization:

Variable

Description

Default

MIFOS_BASE_URL

Base URL of Fineract instance

https://tt.mifos.community

MIFOS_TENANT

Tenant identifier

default

| MIFOS_USERNAME | Self-service username (optional, see below) | none | | MIFOS_PASSWORD | Self-service password (optional, see below) | none | | MIFOS_STEP_UP_CHANNEL | EMAIL, SMS or TOTP: how the verification code reaches the user (see below) | the authenticator app if the user paired one, otherwise the first channel the bank offers | | MIFOS_STEP_UP_ALLOW_CHAT_OTP | false to forbid typing the code in the chat (see below) | true | | MIFOS_TRANSFER_MAX_AMOUNT | Largest transfer the assistant may prepare; larger ones must be made in the bank's app | no limit | | MIFOS_TRANSFER_CONFIRM_TTL_SECONDS | How long a prepared transfer can be confirmed | 300 | | MIFOS_TIMEZONE | The bank's time zone (e.g. America/Mexico_City), used for the transfer date | server's time zone |

Authentication

Tools do not take a username or password. The server keeps the login itself, so the AI never sees the password or the access token. There are two ways to log in:

  1. Recommended: set MIFOS_USERNAME and MIFOS_PASSWORD in the server environment (for example in the env block of the Claude Desktop config). Tools work right away, and the password never goes through the chat.

  2. Ask the assistant to call the login tool. The server keeps the access token from Fineract and returns the login details without the token. Use logout to end the session.

The session lives in the server process. This is safe for the default stdio transport (one server per user); do not share one server between several users.

Transfers: prepare, then confirm

The assistant cannot move money in one call. Every transfer takes two tools:

  1. prepare_transfer(from_account_id, to_account_id, amount, description, ...) moves no money. It checks that the source is one of your accounts and that the destination is one of your own accounts (for example a loan, for a repayment) or, with third_party: true, one of your saved beneficiaries. It checks the amount against MIFOS_TRANSFER_MAX_AMOUNT and the available balance, and returns a summary (accounts, amount, currency, fee) with a confirmation_id. The assistant shows you the summary and asks you to confirm.

  2. confirm_transfer(confirmation_id) sends exactly the request that was prepared. The server keeps it, so the AI cannot change the accounts or the amount in between. The id works once and expires after MIFOS_TRANSFER_CONFIRM_TTL_SECONDS (5 minutes by default; at most 5 prepared transfers are kept). If your client supports MCP elicitation, it also shows you a form ("Send this ... ?") and nothing is sent unless you confirm there (if the form cannot be shown, nothing is sent either). If the bank asks for a one-time code, the confirmation continues as described below.

cancel_transfer(confirmation_id) drops a prepared transfer.

Applying for shares works the same way: prepare_share_application (checks the product's share limits and that the linked savings account is the client's, active and in the product's currency, and returns the total price), then confirm_share_application or cancel_share_application. A share confirmation id cannot confirm a transfer, and the other way round. The bank still has to approve the application.

Adding a beneficiary works the same way, because money can be sent to it later: prepare_beneficiary(name, account_number, office_name, account_type, transfer_limit) checks the account type ("savings" or "loan") against the bank's template and the office against the bank's offices, takes the currency of your own accounts (or the currency you pass) and saves nothing. prepare_beneficiary_change(beneficiary_id, name, transfer_limit) shows the old and new values; the bank only lets the name and the transfer limit change. confirm_beneficiary saves either one, cancel_beneficiary drops it.

Human-in-the-loop confirmation for sensitive tools

When the bank has step-up authentication turned on (selfservice-plugin, MX-488), some operations need a one-time code that the account owner receives by e-mail or SMS: third-party transfers, transfers between your own accounts, and password changes (confirm_transfer, update_account_password). All other tools are unchanged.

The AI never sees the code or the one-time token the bank returns for it. The server asks for the code like this:

  1. The client supports MCP elicitation (a form shown by the client). The tool shows a form such as "A verification code was sent to a***@example.com. Enter it to confirm: third-party transfer of 100.5 from account 11 to account 22." The person types the code there; it goes straight to this server and the tool finishes the transfer in the same call. A wrong code asks again (the form shows the attempts left); declining or cancelling the form stops the operation with cancelled: true and nothing is executed.

  2. The client does not support elicitation. The tool answers step_up_required with a challengeId, a summary of what the code approves and the masked destination, and executes nothing. The assistant must ask you for the code and call verify_step_up(challengeId, otp). Use resend_step_up(challengeId) if the code did not arrive (the bank limits how soon and how often). Typing the code in the chat means the code passes through the AI client and its logs: it is a one-time code that is tied to that one operation, but if you do not accept that, set MIFOS_STEP_UP_ALLOW_CHAT_OTP=false. Then, without elicitation, no code is sent at all and the tool tells the user to confirm in the bank's own app or website.

The request that runs after the code is accepted is the one that was approved. The server keeps it (it is not read from the AI again), and the bank also ties the code to the accounts and the amount, so the AI cannot approve one operation and run another. A waiting operation is kept in memory for 10 minutes and for at most 5 operations.

Step-up needs a login session: call login. Credentials from MIFOS_USERNAME / MIFOS_PASSWORD alone are not enough for this step (the bank answers session.required and the tool says so). MIFOS_STEP_UP_CHANNEL picks SMS or e-mail when the user has both; if that channel is not available the first one the bank offers is used.

Authenticator app

If the bank also offers an authenticator app (Google Authenticator, Microsoft Authenticator...) and the user paired one, the verification uses it (channel TOTP): nothing is sent, the person types the 6-digit code the app shows now. By default the bank offers only the app to such a user (so an intercepted SMS is of no use), and this server then uses it without any setting.

  • With elicitation the form asks for "Code from your authenticator app" and, only for a lost phone, "Recovery code" (one of the codes the user saved when pairing; each works once). The form takes one of the two. A wrong code asks again, as before.

  • Without elicitation the chat fallback accepts only the 6-digit code of the app, which is valid for seconds and for this one operation. A recovery code is never accepted in the chat (it is a long-lived credential); the tool tells the user to use a client with elicitation or the bank's own app. resend_step_up does not apply: an app code cannot be sent again.

  • Pairing, new recovery codes and removing the app are not tools. The secret and the recovery codes must not pass through an AI conversation, so the user does that in the bank's own app or website.

Errors

When the bank refuses a request, tools answer with a short, readable error instead of the bank's raw response:

{"error": true, "status_code": 400,
 "message": "The parameter `productId` is mandatory.",
 "errors": [{"message": "The parameter `productId` is mandatory.", "parameter": "productId"}],
 "code": "validation.msg.validation.errors.exist"}

errors lists the fields to fix and code is the bank's error code. Developer messages, server paths and HTML error pages are never passed on.

Running with Docker

The project includes Docker support for easy deployment:

# Build and run with docker-compose
docker-compose up --build

Using with Claude Desktop (MCP)

  • In Claude Desktop → Settings → Developer → Local MCP servers → Edit Config, add:

{
  "mcpServers": {
    "mifos-banking": {
      "command": "/ABSOLUTE/PATH/TO/venv/bin/python",
      "args": [
        "/ABSOLUTE/PATH/TO/main.py"
      ],
      "env": {
        "MIFOS_BASE_URL": "https://tt.mifos.community",
        "MIFOS_TENANT": "default",
        "MIFOS_USERNAME": "your-username",
        "MIFOS_PASSWORD": "your-password"
      }
    }
  }
}

Restart Claude Desktop after saving.

Running the Server

To run the MCP server, execute the following command from the project's root directory:

python3 main.py

Example Usage (Natural Language) on Claude

Once the MCP server is connected, Claude can invoke the available tools automatically. You can paste the following prompts in Claude Desktop to verify that your configuration is working correctly:

  • Log in (only needed if MIFOS_USERNAME / MIFOS_PASSWORD are not set)

  • Get my client information

  • Show my client accounts

  • List my beneficiaries

  • Get my loan accounts

  • Show my savings accounts

If these commands return valid responses, your MCP server is successfully connected and operational.

Available MCP Tools

The MCP server exposes the following AI-callable tools. Each tool internally maps to a Fineract self-service API call. These tools are invoked by MCP-compatible AI clients, not directly via HTTP.

Authentication

Method

MCP Tool Name

Description

POST

register_self_service_existing_client

Register a self-service user for an existing client

POST

confirm_self_service_user_registration

Confirm the registration with the request id and token

POST

verify_user_registration

Same as confirm_self_service_user_registration

GET

confirm_self_service_user_registration_status

Check the registration: lists the clients the user can see

POST

login

Log in and keep the session in the server

POST

authenticate_user_self_service

Same as login

POST

logout

End the session

PUT

update_account_password

Change the password (asks for a one-time code)

Client & Accounts

Method

MCP Tool Name

Description

GET

get_clients_linked_to_user

The clients linked to the logged-in user (gives the client id)

GET

get_client_details

Retrieve client information

GET

get_client_accounts

Retrieve client accounts

GET

get_client_charges

Retrieve client charges

GET

get_client_images

Retrieve client images

GET

get_client_transactions

Retrieve client transactions

GET

get_client_transaction_detail

Retrieve one client transaction

Beneficiaries

Method

MCP Tool Name

Description

GET

get_beneficiary_list

List all beneficiaries

GET

get_beneficiary_template

The account types a beneficiary can have

-

prepare_beneficiary

Step 1: check a new beneficiary (saves nothing)

-

prepare_beneficiary_change

Step 1: check a new name or transfer limit (saves nothing)

POST/PUT

confirm_beneficiary

Step 2: save the prepared beneficiary or change

-

cancel_beneficiary

Drop a prepared beneficiary or change

DELETE

delete_beneficiary

Delete a beneficiary

Loans

Method

MCP Tool Name

Description

GET

get_loan_products

Retrieve available loan products

GET

get_loan_product_details

Retrieve loan product details

GET

get_loan_account_details

Retrieve loan account details

GET

get_loan_transaction_detail

Retrieve loan transaction detail

GET

get_loan_account_charges

Retrieve loan charges

GET

get_loan_template

Products a client can apply for, or one product's terms and loan purposes

POST

calculate_loan_repayment_calendar

Repayment schedule for an amount and number of repayments (submits nothing)

POST

prepare_loan_application

Step 1: check a new application (or a change to a pending one) and show its schedule

POST

confirm_loan_application

Step 2: submit the prepared application, once, after the user says yes

POST

cancel_loan_application

Drop a prepared application

POST

withdraw_loan_application

Withdraw loan application

Loan applications take typed fields (product, amount, number of repayments, loan purpose, expected disbursement date). Everything else (interest, repayment frequency, product charges) comes from the bank's loan template, and the amount and number of repayments are checked against the product's limits. A loan creates a debt, so prepare_loan_application returns the schedule the bank calculates and submits nothing; confirm_loan_application submits it only with the confirmation id, at most once, and asks the person in a form when the client can show one. Passing loan_id changes an application that is still waiting for approval the same way.

Loan simulation (no login needed)

Method

MCP Tool Name

Description

GET

get_loan_simulation_products

Loan products available for simulation, with their limits

POST

simulate_loan

Estimate interest, total and installments for an amount

Savings

Method

MCP Tool Name

Description

GET

get_savings_products

Get list of savings products

GET

get_savings_product_details

Get savings product details

GET

get_savings_account_details

Get savings account details

GET

get_savings_account_transactions

Get savings account transactions

GET

get_savings_account_transaction_details

Get transaction details

GET

get_savings_account_charges

Get savings account charges

GET

get_savings_account_template_raw

Get savings account template

-

prepare_savings_application

Step 1: check an application for a savings account and get a summary and a confirmation_id (submits nothing)

POST

confirm_savings_application

Step 2: submit the prepared application once, after the user confirmed

-

cancel_savings_application

Drop a prepared application

PUT

update_savings_account_application

Change the product, field officer or external id of an application waiting for approval

Statements & Insights

Read-only tools that reshape a savings account's own transaction list into a statement and spending picture. Everything is computed by the MCP server from the bank's rows — see the "Honest limits" line in each tool's description.

Method

MCP Tool Name

Description

GET

get_account_statement

Date- and direction-filtered statement of one savings account (paged, newest first)

GET

get_spending_summary

Money in / money out totals, monthly buckets and per-type breakdown

GET

find_recurring_payments

Same-amount, evenly-spaced debits (subscriptions, instalments)

Guarantors

Method

MCP Tool Name

Description

GET

get_guarantor_template

Get template for creating guarantors

GET

get_guarantor_list

Get list of guarantors for a loan

POST

create_guarantor

Add a new guarantor for a loan

PUT

update_guarantor

Update an existing guarantor

DELETE

delete_guarantor

Delete a loan guarantor

Shares

Method

MCP Tool Name

Description

GET

get_share_product_list

Get list of share products

GET

get_share_product_details

Get share product details

GET

get_share_account_template

Share products a client can apply for; with product_id, price and share limits

GET

get_share_account

One share account or application

-

prepare_share_application

Step 1: check an application for shares and get a summary and a confirmation_id (submits nothing)

POST

confirm_share_application

Step 2: submit the prepared application once, after the user confirmed

-

cancel_share_application

Drop a prepared application

Notifications

Method

MCP Tool Name

Description

GET

get_user_notification_details

Get notification registration details

POST

register_for_notifications

Register device for push notifications

PUT

update_notification_registration

Update notification registration

Offices

Method

MCP Tool Name

Description

GET

get_offices

List the bank's offices (branches)

GET

get_office_details

Details of one office

GET

get_office_services

Services an office offers, with working hours

GET

get_office_address

Street address of an office

GET

get_office_geolocation

Map location of an office

Profile and pockets

Method

MCP Tool Name

Description

GET

get_user_details

The logged-in user's roles, permissions and clients (banks with OAuth login only; credentials are removed)

GET

get_pockets

The accounts saved as favourites (pockets)

POST

add_accounts_to_pocket

Save the user's loan, savings or share accounts as favourites

POST

remove_accounts_from_pocket

Remove favourites by mapping id (from get_pockets)

GET

get_security_activity

Logins and sensitive actions (password, transfers, beneficiaries), newest first; filter by type

Transfers

Method

MCP Tool Name

Description

GET

get_account_transfer_template

Accounts you can transfer between

GET

get_third_party_transfer_template

Your accounts and saved beneficiaries for third-party transfers

GET

get_transfer_fees

List the bank's transfer fee rules (filter by type and currency)

POST

get_transfer_quote

Ask the bank for the exact fee and total of a transfer (moves no money)

-

prepare_transfer

Step 1: check a transfer and get a summary and a confirmation_id (moves no money)

POST

confirm_transfer

Step 2: send the prepared transfer once, after the user confirmed (may ask for a one-time code)

-

cancel_transfer

Drop a prepared transfer

POST

verify_step_up

Give the code the user received to the operation that waits for it (clients without elicitation)

POST

resend_step_up

Send the code again

License

This project is licensed under the terms included in the LICENSE file.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI assistants to perform Nigerian banking operations including account management, payments, and identity verification through the Mono Open Banking API.
    59
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI agents to interact with the Griffin API for banking operations like opening accounts, creating payments, and managing legal persons.
    13 npm
    14
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables financial management through the Procfy API, allowing AI agents to manage transactions, bank accounts, contacts, and more via natural language.
    1
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI assistants to perform banking operations like creating customers and accounts, checking balances, transferring funds, and viewing transaction history through MCP tools.
    MIT