LIMU Portal MCP

Model Context Protocol server for LIMU Portal operational and finance data. It supports the original local stdio/MySQL mode and a Vercel HTTP mode that authenticates with LIMU OAuth and calls LIMU Portal APIs.

Exposed Data

  • Clients, including editable profile records plus cargo, package, shipment, invoice, payment, order-form, lead, KYC, query, and mobile-account summaries.
  • Cargo records, tracking numbers, clients, shipment links, package totals, and cargo logs, with confirmation-gated cargo creation in Vercel HTTP mode.
  • Cargo package groups, package units, and stage-check summaries, with confirmation-gated package creation in Vercel HTTP mode.
  • Shipments, calendars, status updates, cargo totals, and budget summaries.
  • Monthly budgets, detailed budget entries, and controlled purchase scheduling.
  • Shipment customs budgets and shipping budgets, including income rows, expense rows, and budget logs.
  • Requisitions, requisition items, payment vouchers, voucher items, payment proofs, and controlled approval/payment actions.
  • Client profile reports, lead reports, order form reports, import product reports, leave applications, and timesheet reports.

Setup

cd /Applications/XAMPP/xamppfiles/htdocs/limu/mcp
cp .env.example .env
npm install
npm run smoke

Vercel HTTP MCP

The Vercel entrypoint is:

/api/mcp

It requires an OAuth bearer token issued by the LIMU Portal OAuth provider. The remote server validates tokens through:

GET /Api/v1/oauth/userinfo/

Then each tool forwards that same bearer token to the relevant LIMU Portal API endpoint, keeping portal permissions as the source of truth.

The server publishes OAuth Protected Resource Metadata at:

/.well-known/oauth-protected-resource

The portal publishes authorization server metadata and supports dynamic client registration, so Codex can register its temporary local callback automatically. Manual callback registration is not required.

Set this Vercel environment variable:

LIMU_PORTAL_BASE_URL=https://portal.limu.co.mw

Then deploy:

npm run build

Vercel will serve the MCP route over Streamable HTTP through mcp-handler.

Add the deployed server to Codex and authenticate it:

codex mcp add limu_mcp --url https://limu-mcp.vercel.app/api/mcp
codex mcp login limu_mcp

Run npm run smoke:oauth to verify protected-resource metadata and audience checks locally.

Client creation through the portal

limu_create_client calls POST /Api/v1/clients/create.php. Deploy that PHP endpoint and create-engine.php to the portal before deploying the MCP. It requires clients:write and Clients create permission. It defaults to a server-validated dry run; saving requires dryRun: false and confirm: true. Matching phone numbers or email addresses return HTTP 409 without changing the existing client. The endpoint serializes its own create requests; legacy portal writers do not share that lock. No schema migration is required. Run npm run smoke:client-create for registration, authorization forwarding, preview defaults, validation, and duplicate-conflict checks. Run php ../tests/client-create-validation-test.php from this directory to check the PHP input validator. Rollback: remove the MCP tool registration and the two new PHP files; existing client records need no rollback.

Cargo writes through the portal

  • Cargo and package creation require the cargo:write OAuth scope plus the employee's Cargo create permission.
  • Cargo merge and shipment assignment require cargo:write plus Cargo edit permission.
  • Merge and assignment default to dry-run previews. Execution requires an unchanged SHA-256 preview token, explicit confirmation, and a stable idempotency key.
  • Merges accept only Created, unassigned cargo owned by one client. Source cargo records are deleted after their related records are moved into the approved primary cargo.
  • Shipment assignment accepts only Created, unassigned cargo and changes its status to Booked.
  • Use limu_assign_cargo_shipment with cargoId and shipmentId to preview. Save with dryRun: false, confirm: true, the returned previewToken, and a stable idempotencyKey. Retrying that exact request as the same employee returns the saved result, even though the cargo is now Booked; reusing the key for different cargo, shipment, or preview is rejected.
  • Run npm run smoke:assignment for assignment defaults, confirmation guards, authenticated forwarding, retries, and API error propagation. The portal deployment runs PHP assignment validation and retry checks before uploading files.

The remote migration currently covers OAuth-protected health/userinfo, clients, cargo, cargo packages, shipments, monthly budgets, budget reports, purchase schedules, imports-and-orders, import-product, leads, client-profile reports, and a controlled QuickBooks accounting slice. The leads report returns conversion, source, segment, tag, and pipeline analytics while enforcing the viewer's portal report permissions. The client-profile report summarizes clients active in a selected cargo-activity period, including demographics, tiers, and relations-officer coverage. Requisition, payment voucher, and leave tools remain registered with explicit "portal endpoint pending" responses until their matching portal endpoints are added.

Cargo status corrections through the portal

limu_update_cargo_status calls POST /Api/v1/cargo/update-status.php. Deploy that endpoint and status-update-engine.php before the MCP release. It requires an authenticated employee, cargo:write, and Cargo edit permission. It accepts assigned cargo only; Created/Booked are handled by the existing creation and assignment tools.

Provide cargoId, expectedShipmentId, the exact expectedStatus, the requested status (including Collected), and a 3โ€“500 character reason. Calls default to a server-validated preview with no writes. To save, reuse the preview token with dryRun: false, confirm: true, and a stable idempotencyKey. Stale cargo/shipment/owner state returns a conflict. Exact retries by the same employee return the original result; key reuse with different input is rejected.

This is an administrative status correction. It changes only cargo.cargostatus, with a cargo log and the existing MCP audit row in one transaction. It does not create a collection receipt, invent collector details, change finance/dispatch fields, or send notifications. Same-status requests are no-ops. No schema migration is required; the existing audit-table helper is reused only on confirmed calls.

Validation: npm run smoke:cargo-status and php tests/cargo-status-update-test.php in the portal. The Cargo status checks workflow also runs MySQL integration tests for save/retry/no-op behavior, stale previews, unrelated-field isolation, and rollback on log failure. Rollback: remove the MCP registration and the two new PHP files; already saved audit/history rows remain intact.

QuickBooks through the portal

The portal is the sole owner of the QuickBooks OAuth connection and keeps its Intuit tokens in the portal database. The MCP never receives or returns those credentials.

  • Read tools require the quickbooks:read OAuth scope and an Accounts, Customs, or Payment Vouchers view permission.
  • Invoice, bill, customer-payment, and bill-payment tools require quickbooks:write plus Accounts, Customs, or Payment Vouchers management permission.
  • Financial write tools default to dryRun: true; a real post requires both dryRun: false and confirm: true.
  • Every post requires a stable sourceReference and idempotencyKey. The portal records a local audit row and sends a matching QuickBooks requestid to prevent accidental duplicate postings.
  • Direct journal entries, updates, and deletes are deliberately not exposed.

Local Stdio MCP

Use a least-privilege MySQL user. A read-only user is enough for reporting tools, but write tools need narrowly scoped UPDATE access for Clients, monthly_budget_entry, and leave_applications, INSERT/UPDATE/DELETE access for monthly budget schedule splits, UPDATE/INSERT access for leave logs, requisitions, requisition logs, payment vouchers, and budget spend tables, plus DELETE access for eligible requisitions, requisition items/logs, payment vouchers, voucher items, and voucher proof rows.Write tools require confirm: true; use dryRun: true first to preview the exact proposed change.Client auth secrets, token hashes, KYC link tokens, and government ID numbers are intentionally omitted from client tool responses.

Run

cd /Applications/XAMPP/xamppfiles/htdocs/limu/mcp
npm start

Most MCP clients should launch it over stdio. Example client config:

{
  "mcpServers": {
    "limu-portal": {
      "command": "node",
      "args": [
        "/Applications/XAMPP/xamppfiles/htdocs/limu/mcp/src/server.js"
      ],
      "env": {
        "LIMU_DB_HOST": "127.0.0.1",
        "LIMU_DB_PORT": "3306",
        "LIMU_DB_NAME": "limutradee",
        "LIMU_DB_USER": "root",
        "LIMU_DB_PASSWORD": ""
      }
    }
  }
}

Tools

  • limu_health
  • limu_get_clients
  • limu_get_client
  • limu_create_client (Vercel HTTP mode)
  • limu_update_client
  • limu_list_cargo
  • limu_get_cargo
  • limu_update_cargo_status (Vercel HTTP mode)
  • limu_create_cargo
  • limu_merge_cargo
  • limu_assign_cargo_shipment
  • limu_sync_cargo_package_count
  • limu_get_cargo_action_audit
  • limu_list_packages
  • limu_get_package
  • limu_create_package
  • limu_update_package
  • limu_list_cargo_content_categories
  • limu_list_shipments
  • limu_get_shipment
  • limu_get_imports_and_orders_report
  • limu_get_import_product_report
  • limu_list_monthly_budgets
  • limu_get_monthly_budget
  • limu_get_budget_report
  • limu_list_purchase_schedule
  • limu_schedule_budget_purchase
  • limu_list_shipment_budgets
  • limu_get_shipment_budget
  • limu_list_customs_budgets
  • limu_get_customs_budget
  • limu_list_shipping_budgets
  • limu_get_shipping_budget
  • limu_list_requisitions
  • limu_get_requisition
  • limu_review_requisition
  • limu_delete_requisition
  • limu_list_payment_vouchers
  • limu_get_payment_voucher
  • limu_review_payment_voucher
  • limu_delete_payment_voucher
  • limu_mark_payment_voucher_paid
  • limu_list_client_profile_reports
  • limu_get_client_profile_report
  • limu_list_lead_reports
  • limu_get_lead_report
  • limu_list_order_form_reports
  • limu_get_order_form_report
  • limu_list_leave_applications
  • limu_review_leave_application
  • limu_list_timesheet_reports
  • limu_list_warehouse_timesheet_reports

All tools return JSON text payloads and list tools enforce a configurable limit cap.

MCP Server ยท Populars

MCP Server ยท New

    MCP-Manager

    MCP Security Checklists

    MCP Server

    Community MCP-Manager
    mozarkai

    Optics Framework

    Open-source test automation for Android, iOS, web, smart TV (Android TV, Tizen, webOS) and Bluetooth (BLE) devices. Write tests as CSV/YAML, record them live, or let an AI agent build them over MCP. Self-healing locators: XPath, text, OCR, image.

    Community mozarkai
    baronunread

    rdyrct

    Open-source URL shortener for teams: branded short links, QR codes, and custom domains on Cloudflare Workers.

    Community baronunread
    ExpeditedProjects

    HutchDB

    A database for AI agents. No schema, SQL, or structure required. Claude Code, Codex, Cursor, Hermes, Claw, Grokbot, and other MCP clients store, query, and share the same records. Open source (AGPLv3) or cloud.

    Community ExpeditedProjects
    heubme2020

    DataSinking

    Full-text financial reports (US, China, Japan, Korea, Taiwan) as clean Markdown โ€” REST API + MCP server for LLMs, RAG and quant

    Community heubme2020