MCP Servers

A collection of Model Context Protocol servers, templates, tools and more.

Enterprise ERP MCP Server — SAP, NetSuite, Odoo, Zoho Books, Business Central with lifecycle-based document management

Created 5/25/2026
Updated about 18 hours ago
Repository documentation and setup instructions

ERP MCP Server

Crates.io License ADK-Rust Enterprise Registry Ready

The most complete multi-backend ERP MCP server. 34 tools across 5 backends — SAP S/4HANA, NetSuite, Odoo, Zoho Books, and Microsoft Dynamics 365 Business Central. Lifecycle-based document management with governed write operations. Single Rust binary with feature-flagged backends and enterprise governance.

Architecture

MCP ERP Architecture

Key Principles

  • Unified schema — agents see consistent types (Customer, Vendor, Product, SalesOrder, Invoice) regardless of backend
  • Lifecycle-based writes — documents progress through states (draft → pending_approval → approved → released → posted → closed) instead of single-step creates
  • Feature-flagged backends — compile only what you need (--features zoho,odoo,sap)
  • Financial governance — invoice posting and order submission require approval gates
  • No credential exposure — tokens stay in env vars, never reach LLM context
  • Single binary — no Node.js, no Python, no runtime dependencies

Comparison with Other ERP Integrations

| Feature | Generic REST | Zapier/Make | mcp-erp | |---------|:---:|:---:|:---:| | Multi-backend (5 ERPs) | ❌ | Partial | ✅ | | Unified schema | ❌ | ❌ | ✅ | | Lifecycle state tracking | ❌ | ❌ | ✅ | | Draft → Submit → Post flow | ❌ | ❌ | ✅ | | Risk classification per tool | ❌ | ❌ | ✅ | | Approval gates | ❌ | ❌ | ✅ | | Audit trail | ❌ | Partial | ✅ | | Single binary | ❌ | ❌ | ✅ | | Registry governance | ❌ | ❌ | ✅ | | Agent-native (MCP) | ❌ | ❌ | ✅ |

Tools (34)

Customers (4)

| Tool | Purpose | Risk Class | |------|---------|------------| | list_customers | List customers with optional filters | Read-only | | get_customer | Get a customer by ID | Read-only | | create_customer | Create a new customer record | Internal write | | update_customer | Update an existing customer record | Internal write |

Vendors (4)

| Tool | Purpose | Risk Class | |------|---------|------------| | list_vendors | List vendors/suppliers with optional filters | Read-only | | get_vendor | Get a vendor by ID | Read-only | | create_vendor | Create a new vendor/supplier record | Internal write | | update_vendor | Update an existing vendor record | Internal write |

Products (4)

| Tool | Purpose | Risk Class | |------|---------|------------| | list_products | List products/items with optional filters | Read-only | | get_product | Get a product by ID | Read-only | | create_product | Create a new product/item record | Internal write | | update_product | Update an existing product record | Internal write |

Sales Orders (4)

| Tool | Purpose | Risk Class | |------|---------|------------| | list_sales_orders | List sales orders with optional filters | Read-only | | get_sales_order | Get a sales order by ID with line items | Read-only | | create_sales_order_draft | Create a sales order in draft state | Internal write | | submit_sales_order | Submit a draft sales order for approval/release | External write |

Purchase Orders (4)

| Tool | Purpose | Risk Class | |------|---------|------------| | list_purchase_orders | List purchase orders with optional filters | Read-only | | get_purchase_order | Get a purchase order by ID with line items | Read-only | | create_purchase_order_draft | Create a purchase order in draft state | Internal write | | submit_purchase_order | Submit a draft purchase order for approval/release | External write |

Invoices (5)

| Tool | Purpose | Risk Class | |------|---------|------------| | list_invoices | List invoices with optional filters | Read-only | | get_invoice | Get an invoice by ID with line items and payment status | Read-only | | create_invoice_draft | Create an invoice in draft state | Internal write | | submit_invoice | Submit a draft invoice for approval | Financial action | | post_invoice | Post an approved invoice to the ledger | Financial action |

Inventory (3)

| Tool | Purpose | Risk Class | |------|---------|------------| | get_stock_levels | Get current stock levels for products | Read-only | | adjust_stock | Adjust stock quantity (increase/decrease) | Internal write | | transfer_stock | Transfer stock between warehouses/locations | Internal write |

General Ledger (3) — Read-only

| Tool | Purpose | Risk Class | |------|---------|------------| | list_accounts | List chart of accounts | Read-only | | get_journal_entries | Get journal entries for a date range | Read-only | | get_trial_balance | Get trial balance for a period | Read-only |

Governance (3)

| Tool | Purpose | Risk Class | |------|---------|------------| | request_erp_approval | Request approval for a pending ERP document | Internal write | | attach_erp_evidence | Attach supporting evidence/documents to a record | Internal write | | get_erp_audit_trail | Get the audit trail/history for a document | Read-only |

Document Lifecycle

All transactional documents (orders, invoices) carry a lifecycle state:

draft → pending_approval → approved → released → posted → sent → fulfilled → closed
                                                                          ↘ cancelled / voided
  • create_*_draft tools create documents in draft state (low risk, no side effects)
  • submit_* tools advance to pending_approval or released (requires approval)
  • post_invoice advances to posted (financial action, irreversible in most ERPs)

Backends

| Backend | Protocol | Auth | Default Feature | |---------|----------|------|:---:| | Zoho Books | REST | OAuth2 | ✅ | | Odoo | JSON-RPC | Session | ✅ | | Business Central | OData v4 | Azure AD OAuth2 | ❌ | | NetSuite | REST | OAuth 1.0a | ❌ | | SAP S/4HANA | OData | OAuth2 / Basic | ❌ |

Backend Capabilities

| Capability | Zoho | Odoo | BC | NetSuite | SAP | |-----------|:---:|:---:|:---:|:---:|:---:| | Customers/Vendors | ✅ | ✅ | ✅ | ✅ | ✅ | | Products | ✅ | ✅ | ✅ | ✅ | ✅ | | Sales Orders | ✅ | ✅ | ✅ | ✅ | ✅ | | Purchase Orders | ✅ | ✅ | ✅ | ✅ | ✅ | | Invoices (draft/post) | ✅ | ✅ | ✅ | ✅ | Via SO flow | | Stock Levels | ✅ | ✅ | ✅ | ✅ | ✅ | | Stock Adjustments | ✅ | ✅ | ✅ | ✅ | ✅ | | Stock Transfers | ✅ | ❌¹ | ✅ | ✅ | ✅ | | Chart of Accounts | ✅ | ✅ | ✅ | ✅ | ✅ | | Journal Entries | ✅ | ✅ | ✅ | ✅ | ✅ | | Audit Trail | ❌ | ✅² | ❌ | ❌ | ❌ |

¹ Odoo stock transfers require the picking workflow — use the Odoo UI
² Odoo audit trail uses the mail.message model

Installation

cargo install mcp-erp --features all-backends

Or build from source:

git clone https://github.com/zavora-ai/mcp-erp
cd mcp-erp
cargo build --release --features all-backends

Feature flags

# Default: Zoho + Odoo (lightest)
cargo install mcp-erp

# All backends
cargo install mcp-erp --features all-backends

# Specific backends
cargo install mcp-erp --no-default-features --features sap
cargo install mcp-erp --no-default-features --features "zoho,business-central"

Configuration

Zoho Books

export ZOHO_TOKEN="1000.xxxx"
export ZOHO_ORG_ID="12345678"

Odoo

export ODOO_URL="https://mycompany.odoo.com"
export ODOO_DB="mycompany"
export ODOO_USER="admin"
export ODOO_PASSWORD="secret"

Microsoft Dynamics 365 Business Central

export BC_TENANT_ID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
export BC_ENVIRONMENT="production"
export BC_COMPANY_ID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
export BC_TOKEN="eyJ0eXAi..."

NetSuite

export NETSUITE_ACCOUNT_ID="1234567_SB1"
export NETSUITE_CONSUMER_KEY="xxxx"
export NETSUITE_CONSUMER_SECRET="xxxx"
export NETSUITE_TOKEN_ID="xxxx"
export NETSUITE_TOKEN_SECRET="xxxx"

SAP S/4HANA

export SAP_BASE_URL="https://myhost.s4hana.cloud.sap"
export SAP_TOKEN="eyJ0eXAi..."

Client Configuration

Claude Desktop

{
  "mcpServers": {
    "erp": {
      "command": "mcp-erp",
      "args": [],
      "env": {
        "ZOHO_TOKEN": "1000.xxxx",
        "ZOHO_ORG_ID": "12345678"
      }
    }
  }
}

Kiro

Add to .kiro/settings/mcp.json:

{
  "mcpServers": {
    "erp": {
      "command": "mcp-erp",
      "args": [],
      "env": {
        "ODOO_URL": "https://mycompany.odoo.com",
        "ODOO_DB": "mycompany",
        "ODOO_USER": "admin",
        "ODOO_PASSWORD": "secret"
      }
    }
  }
}

Cursor

Add to .cursor/mcp.json:

{
  "mcpServers": {
    "erp": {
      "command": "mcp-erp",
      "args": [],
      "env": {
        "SAP_BASE_URL": "https://myhost.s4hana.cloud.sap",
        "SAP_TOKEN": "eyJ0eXAi..."
      }
    }
  }
}

Windsurf

Add to ~/.codeium/windsurf/mcp_config.json:

{
  "mcpServers": {
    "erp": {
      "command": "mcp-erp",
      "args": [],
      "env": {
        "BC_TENANT_ID": "xxx",
        "BC_ENVIRONMENT": "production",
        "BC_COMPANY_ID": "xxx",
        "BC_TOKEN": "eyJ..."
      }
    }
  }
}

Usage Examples

List and inspect customers

"List our top 10 customers"
→ list_customers(limit: 10)

"Get details for customer C-001"
→ get_customer(id: "C-001")

Create and submit a sales order

"Create a draft sales order for customer C-001 with 50 units of SKU-A at $25 each"
→ create_sales_order_draft(party_id: "C-001", line_items: [{description: "SKU-A", quantity: 50, unit_price: 25.0}])

"Submit that order for approval"
→ submit_sales_order(id: "SO-12345")

Invoice lifecycle

"Create a draft invoice for customer C-001"
→ create_invoice_draft(customer_id: "C-001", line_items: [...])

"Submit the invoice for approval"
→ submit_invoice(id: "INV-789")

"Post the approved invoice to the ledger"
→ post_invoice(id: "INV-789")

Inventory management

"What's our current stock of product P-100?"
→ get_stock_levels(product_id: "P-100")

"Add 200 units of P-100 — received from supplier"
→ adjust_stock(product_id: "P-100", quantity: 200, reason: "PO receipt")

"Transfer 50 units from warehouse A to warehouse B"
→ transfer_stock(product_id: "P-100", from_warehouse: "WH-A", to_warehouse: "WH-B", quantity: 50)

Financial reporting

"Show me the trial balance as of end of last month"
→ get_trial_balance(as_of: "2026-04-30")

"Get journal entries for May 2026"
→ get_journal_entries(from: "2026-05-01", to: "2026-05-31")

Governance

"Request approval for sales order SO-12345"
→ request_erp_approval(entity_type: "sales_order", entity_id: "SO-12345")

"Show the audit trail for invoice INV-789"
→ get_erp_audit_trail(entity_type: "invoice", entity_id: "INV-789")

Documentation

| Document | Description | |----------|-------------| | Architecture | System diagram | | mcp-server.toml | ADK-Rust Enterprise registry manifest | | LICENSE | Apache-2.0 license |

Registry Compliance

This server implements the ADK MCP SDK contract:

  • HealthCheck — verifies backend connectivity on startup
  • mcp-server.toml — manifest with 34 tools, risk classes, and credential bindings
  • Manifest validation — startup fails fast on invalid manifest (SDK 0.1.3+)
  • Structured tracingRUST_LOG env-filter for observability

Contributors

| jkmaina - MCP Erp by zavora-ai
James Karanja Maina
| |:---:|

License

Apache-2.0 — see LICENSE for details.


Part of the ADK-Rust Enterprise MCP server ecosystem.

Built with ❤️ by Zavora AI

Quick Setup
Installation guide for this server

Installation Command (package not published)

git clone https://github.com/zavora-ai/mcp-erp
Manual Installation: Please check the README for detailed setup instructions and any additional dependencies required.

Cursor configuration (mcp.json)

{ "mcpServers": { "zavora-ai-mcp-erp": { "command": "git", "args": [ "clone", "https://github.com/zavora-ai/mcp-erp" ] } } }