# Enterich MCP server

> Allows an AI client to interact with ERPNext accounting by reading data and creating draft documents through a secure OAuth-protected interface.

- Repository: https://github.com/Interlusion/enterich
- Page: https://hostedmcp.org/servers/interlusion/enterich
- Transport: remote
- Stars: 0
- License: Apache-2.0
- Latest version: 0.5.0

## Install

### Claude Code

```sh
claude mcp add --env 'ENTERICH_ERPNEXT_API_KEY=<YOUR_ENTERICH_ERPNEXT_API_KEY>' --env 'ENTERICH_ERPNEXT_API_SECRET=<YOUR_ENTERICH_ERPNEXT_API_SECRET>' --env 'ENTERICH_CLIENT_ID=<ENTERICH_CLIENT_ID>' --env 'ENTERICH_COMPANY=<ENTERICH_COMPANY>' --env 'ENTERICH_ERPNEXT_PUBLIC_URL=<ENTERICH_ERPNEXT_PUBLIC_URL>' --env 'ENTERICH_ERPNEXT_URL=<ENTERICH_ERPNEXT_URL>' --env 'ENTERICH_ISSUER=<ENTERICH_ISSUER>' --env 'ENTERICH_JWKS_URL=<ENTERICH_JWKS_URL>' --env 'ENTERICH_RESOURCE_URL=<ENTERICH_RESOURCE_URL>' --env 'ENTERICH_SUBJECT=<ENTERICH_SUBJECT>' enterich -- docker run -i --rm ghcr.io/interlusion/enterich:0.5.0
```

### Cursor (`~/.cursor/mcp.json`)

```json
{
  "mcpServers": {
    "enterich": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "ghcr.io/interlusion/enterich:0.5.0"
      ],
      "env": {
        "ENTERICH_ERPNEXT_API_KEY": "<YOUR_ENTERICH_ERPNEXT_API_KEY>",
        "ENTERICH_ERPNEXT_API_SECRET": "<YOUR_ENTERICH_ERPNEXT_API_SECRET>",
        "ENTERICH_CLIENT_ID": "<ENTERICH_CLIENT_ID>",
        "ENTERICH_COMPANY": "<ENTERICH_COMPANY>",
        "ENTERICH_ERPNEXT_PUBLIC_URL": "<ENTERICH_ERPNEXT_PUBLIC_URL>",
        "ENTERICH_ERPNEXT_URL": "<ENTERICH_ERPNEXT_URL>",
        "ENTERICH_ISSUER": "<ENTERICH_ISSUER>",
        "ENTERICH_JWKS_URL": "<ENTERICH_JWKS_URL>",
        "ENTERICH_RESOURCE_URL": "<ENTERICH_RESOURCE_URL>",
        "ENTERICH_SUBJECT": "<ENTERICH_SUBJECT>"
      }
    }
  }
}
```

### VS Code (`.vscode/mcp.json`)

```json
{
  "servers": {
    "enterich": {
      "type": "stdio",
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "ghcr.io/interlusion/enterich:0.5.0"
      ],
      "env": {
        "ENTERICH_ERPNEXT_API_KEY": "<YOUR_ENTERICH_ERPNEXT_API_KEY>",
        "ENTERICH_ERPNEXT_API_SECRET": "<YOUR_ENTERICH_ERPNEXT_API_SECRET>",
        "ENTERICH_CLIENT_ID": "<ENTERICH_CLIENT_ID>",
        "ENTERICH_COMPANY": "<ENTERICH_COMPANY>",
        "ENTERICH_ERPNEXT_PUBLIC_URL": "<ENTERICH_ERPNEXT_PUBLIC_URL>",
        "ENTERICH_ERPNEXT_URL": "<ENTERICH_ERPNEXT_URL>",
        "ENTERICH_ISSUER": "<ENTERICH_ISSUER>",
        "ENTERICH_JWKS_URL": "<ENTERICH_JWKS_URL>",
        "ENTERICH_RESOURCE_URL": "<ENTERICH_RESOURCE_URL>",
        "ENTERICH_SUBJECT": "<ENTERICH_SUBJECT>"
      }
    }
  }
}
```

### VS Code CLI

```sh
code --add-mcp '{"name":"enterich","type":"stdio","command":"docker","args":["run","-i","--rm","ghcr.io/interlusion/enterich:0.5.0"],"env":{"ENTERICH_ERPNEXT_API_KEY":"<YOUR_ENTERICH_ERPNEXT_API_KEY>","ENTERICH_ERPNEXT_API_SECRET":"<YOUR_ENTERICH_ERPNEXT_API_SECRET>","ENTERICH_CLIENT_ID":"<ENTERICH_CLIENT_ID>","ENTERICH_COMPANY":"<ENTERICH_COMPANY>","ENTERICH_ERPNEXT_PUBLIC_URL":"<ENTERICH_ERPNEXT_PUBLIC_URL>","ENTERICH_ERPNEXT_URL":"<ENTERICH_ERPNEXT_URL>","ENTERICH_ISSUER":"<ENTERICH_ISSUER>","ENTERICH_JWKS_URL":"<ENTERICH_JWKS_URL>","ENTERICH_RESOURCE_URL":"<ENTERICH_RESOURCE_URL>","ENTERICH_SUBJECT":"<ENTERICH_SUBJECT>"}}'
```

### Claude Desktop (`claude_desktop_config.json`)

```json
{
  "mcpServers": {
    "enterich": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "ghcr.io/interlusion/enterich:0.5.0"
      ],
      "env": {
        "ENTERICH_ERPNEXT_API_KEY": "<YOUR_ENTERICH_ERPNEXT_API_KEY>",
        "ENTERICH_ERPNEXT_API_SECRET": "<YOUR_ENTERICH_ERPNEXT_API_SECRET>",
        "ENTERICH_CLIENT_ID": "<ENTERICH_CLIENT_ID>",
        "ENTERICH_COMPANY": "<ENTERICH_COMPANY>",
        "ENTERICH_ERPNEXT_PUBLIC_URL": "<ENTERICH_ERPNEXT_PUBLIC_URL>",
        "ENTERICH_ERPNEXT_URL": "<ENTERICH_ERPNEXT_URL>",
        "ENTERICH_ISSUER": "<ENTERICH_ISSUER>",
        "ENTERICH_JWKS_URL": "<ENTERICH_JWKS_URL>",
        "ENTERICH_RESOURCE_URL": "<ENTERICH_RESOURCE_URL>",
        "ENTERICH_SUBJECT": "<ENTERICH_SUBJECT>"
      }
    }
  }
}
```

### Codex

```sh
codex mcp add enterich --env 'ENTERICH_ERPNEXT_API_KEY=<YOUR_ENTERICH_ERPNEXT_API_KEY>' --env 'ENTERICH_ERPNEXT_API_SECRET=<YOUR_ENTERICH_ERPNEXT_API_SECRET>' --env 'ENTERICH_CLIENT_ID=<ENTERICH_CLIENT_ID>' --env 'ENTERICH_COMPANY=<ENTERICH_COMPANY>' --env 'ENTERICH_ERPNEXT_PUBLIC_URL=<ENTERICH_ERPNEXT_PUBLIC_URL>' --env 'ENTERICH_ERPNEXT_URL=<ENTERICH_ERPNEXT_URL>' --env 'ENTERICH_ISSUER=<ENTERICH_ISSUER>' --env 'ENTERICH_JWKS_URL=<ENTERICH_JWKS_URL>' --env 'ENTERICH_RESOURCE_URL=<ENTERICH_RESOURCE_URL>' --env 'ENTERICH_SUBJECT=<ENTERICH_SUBJECT>' -- docker run -i --rm ghcr.io/interlusion/enterich:0.5.0
```

### Codex config.toml (`~/.codex/config.toml`)

```toml
[mcp_servers.enterich]
command = "docker"
args = ["run", "-i", "--rm", "ghcr.io/interlusion/enterich:0.5.0"]

[mcp_servers.enterich.env]
ENTERICH_ERPNEXT_API_KEY = "<YOUR_ENTERICH_ERPNEXT_API_KEY>"
ENTERICH_ERPNEXT_API_SECRET = "<YOUR_ENTERICH_ERPNEXT_API_SECRET>"
ENTERICH_CLIENT_ID = "<ENTERICH_CLIENT_ID>"
ENTERICH_COMPANY = "<ENTERICH_COMPANY>"
ENTERICH_ERPNEXT_PUBLIC_URL = "<ENTERICH_ERPNEXT_PUBLIC_URL>"
ENTERICH_ERPNEXT_URL = "<ENTERICH_ERPNEXT_URL>"
ENTERICH_ISSUER = "<ENTERICH_ISSUER>"
ENTERICH_JWKS_URL = "<ENTERICH_JWKS_URL>"
ENTERICH_RESOURCE_URL = "<ENTERICH_RESOURCE_URL>"
ENTERICH_SUBJECT = "<ENTERICH_SUBJECT>"
```

### Gemini CLI

```sh
gemini mcp add -s user -e 'ENTERICH_ERPNEXT_API_KEY=<YOUR_ENTERICH_ERPNEXT_API_KEY>' -e 'ENTERICH_ERPNEXT_API_SECRET=<YOUR_ENTERICH_ERPNEXT_API_SECRET>' -e 'ENTERICH_CLIENT_ID=<ENTERICH_CLIENT_ID>' -e 'ENTERICH_COMPANY=<ENTERICH_COMPANY>' -e 'ENTERICH_ERPNEXT_PUBLIC_URL=<ENTERICH_ERPNEXT_PUBLIC_URL>' -e 'ENTERICH_ERPNEXT_URL=<ENTERICH_ERPNEXT_URL>' -e 'ENTERICH_ISSUER=<ENTERICH_ISSUER>' -e 'ENTERICH_JWKS_URL=<ENTERICH_JWKS_URL>' -e 'ENTERICH_RESOURCE_URL=<ENTERICH_RESOURCE_URL>' -e 'ENTERICH_SUBJECT=<ENTERICH_SUBJECT>' enterich docker -- run -i --rm ghcr.io/interlusion/enterich:0.5.0
```

### Gemini settings.json (`~/.gemini/settings.json`)

```json
{
  "mcpServers": {
    "enterich": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "ghcr.io/interlusion/enterich:0.5.0"
      ],
      "env": {
        "ENTERICH_ERPNEXT_API_KEY": "<YOUR_ENTERICH_ERPNEXT_API_KEY>",
        "ENTERICH_ERPNEXT_API_SECRET": "<YOUR_ENTERICH_ERPNEXT_API_SECRET>",
        "ENTERICH_CLIENT_ID": "<ENTERICH_CLIENT_ID>",
        "ENTERICH_COMPANY": "<ENTERICH_COMPANY>",
        "ENTERICH_ERPNEXT_PUBLIC_URL": "<ENTERICH_ERPNEXT_PUBLIC_URL>",
        "ENTERICH_ERPNEXT_URL": "<ENTERICH_ERPNEXT_URL>",
        "ENTERICH_ISSUER": "<ENTERICH_ISSUER>",
        "ENTERICH_JWKS_URL": "<ENTERICH_JWKS_URL>",
        "ENTERICH_RESOURCE_URL": "<ENTERICH_RESOURCE_URL>",
        "ENTERICH_SUBJECT": "<ENTERICH_SUBJECT>"
      }
    }
  }
}
```

## Environment variables

| Name | Required | Secret | Description |
|---|---|---|---|
| `ENTERICH_ERPNEXT_API_KEY` | yes | yes | The ERPNext agent user's API key |
| `ENTERICH_ERPNEXT_API_SECRET` | yes | yes | The ERPNext agent user's API secret |
| `ENTERICH_CLIENT_ID` | yes | no | The OAuth client the agent's tokens are issued to |
| `ENTERICH_COMPANY` | yes | no | The assigned company, exactly as named in ERPNext |
| `ENTERICH_ERPNEXT_PUBLIC_URL` | yes | no | The base URL people open ERPNext at, for links in results |
| `ENTERICH_ERPNEXT_URL` | yes | no | The base URL Enterich calls ERPNext at |
| `ENTERICH_ISSUER` | yes | no | The authorization server's issuer, https |
| `ENTERICH_JWKS_URL` | yes | no | The authorization server's signing keys, https |
| `ENTERICH_RESOURCE_URL` | yes | no | The MCP endpoint exactly as clients enter it, https; its path is the one served |
| `ENTERICH_SUBJECT` | yes | no | The agent identity's sub |
| `ENTERICH_CLOCK_LEEWAY` | no | no | Seconds of clock leeway for token times, 0 to 60 |
| `ENTERICH_ERPNEXT_HOST` | no | no | The Host header sent to ERPNext, by default the URL's host |
| `ENTERICH_HOST` | no | no | The listen address |
| `ENTERICH_LOG_LEVEL` | no | no | The level for libraries' log lines: DEBUG, INFO, WARNING or ERROR |
| `ENTERICH_MAX_DRAFTS_PER_HOUR` | no | no | Most drafts of each type the agent may create in an hour; unset, no limit |
| `ENTERICH_PORT` | no | no | The listen port |
| `ENTERICH_REQUIRED_SCOPES` | no | no | Scopes required in the token, space-separated |
| `ENTERICH_TIMEZONE` | no | no | IANA time zone for today's date, the ERPNext site's |
| `ENTERICH_TOKEN_ALGORITHMS` | no | no | Token signing algorithms accepted, comma-separated |
| `ENTERICH_TOOLS` | no | no | The operations to offer, comma-separated; by default all |

## Tools (37)

- `list_items`
- `get_item`
- `list_customers`
- `get_customer`
- `list_sales_invoices`
- `get_sales_invoice`
- `list_sales_tax_templates`
- `report_accounts_receivable`
- `create_draft_sales_invoice`
- `update_draft_sales_invoice`
- `create_draft_sales_return`
- `update_draft_sales_return`
- `list_suppliers`
- `get_supplier`
- `list_purchase_invoices`
- `get_purchase_invoice`
- `list_purchase_tax_templates`
- `report_accounts_payable`
- `create_draft_purchase_invoice`
- `update_draft_purchase_invoice`
- `create_draft_purchase_return`
- `update_draft_purchase_return`
- `list_accounts`
- `list_cost_centers`
- `list_journal_entries`
- `get_journal_entry`
- `report_general_ledger`
- `report_trial_balance`
- `create_draft_journal_entry`
- `update_draft_journal_entry`
- `list_bank_accounts`
- `list_bank_transactions`
- `get_bank_transaction`
- `list_payment_entries`
- `get_payment_entry`
- `create_draft_payment_entry`
- `update_draft_payment_entry`

## FAQ

### Can the server submit or delete documents in ERPNext?

No, the server only prepares drafts. A human must review and submit them within ERPNext.

### How does authentication work with Enterich?

It uses tokens from an external OAuth authorization server, such as Keycloak, to verify access.
