@hvgllc/hvgerp-mcp 3.0.3 → 3.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -5,8 +5,8 @@
5
5
  [![MCP](https://img.shields.io/badge/MCP-server-1f6feb?logo=modelcontextprotocol&logoColor=white)](https://modelcontextprotocol.io)
6
6
  [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
7
7
 
8
- MCP server for [ERPNext](https://erpnext.com) / Frappe ERP — **125 tools**
9
- across **14 categories**, with **7 interactive UI viewers**.
8
+ MCP server for [ERPNext](https://erpnext.com) / Frappe ERP: **135 tools** across
9
+ **16 categories**, with **7 interactive UI viewers**.
10
10
 
11
11
  Connect any MCP-compatible AI agent (Claude Desktop, Claude Code, VS Code
12
12
  Copilot, custom) to your ERPNext instance via the
@@ -223,33 +223,58 @@ npm install
223
223
  node build-all.mjs
224
224
  ```
225
225
 
226
- ## Tools (125)
226
+ ## Tools (135)
227
227
 
228
- 125 tools across 14 categories. Each `_list` tool returns interactive results
228
+ 135 tools across 16 categories. Most `_list` tools return interactive results
229
229
  via the doclist-viewer with row click, inline detail, and cross-viewer
230
- navigation.
231
-
230
+ navigation. The read-only `erpnext_stock_ledger_list` instead returns bounded
231
+ ledger rows for the stock viewer's Recent Movements panel.
232
+
233
+ - **Identity** (2) — `erpnext_whoami` (who the server believes the caller is:
234
+ User id, roles, linked Employee, and whether the connection is per-caller or a
235
+ shared service account) and `erpnext_my_work` (everything currently open for
236
+ that person). Call `erpnext_whoami` before answering any first-person request:
237
+ every other tool needs a concrete user or employee id, and this is the only
238
+ one that produces it.
232
239
  - **Sales** (17) — Customers, Sales Orders, Invoices, and Quotations with full
233
240
  CRUD, Submit, and Cancel.
234
241
  - **Purchasing** (11) — Suppliers, Purchase Orders, Purchase Invoices, Receipts,
235
242
  and Supplier Quotations.
236
- - **Inventory** (9) — Items, Stock Balance, Warehouses, and Stock Entries.
237
- - **Accounting** (6) — Chart of Accounts, Journal Entries, and Payment Entries.
238
- - **HR** (12) — Employees, Attendance, Leave Applications, Salary Slips, Payroll
239
- Entries, and Expense Claims.
243
+ - **Inventory** (10): Items, Stock Balance, Warehouses, Stock Entries, and
244
+ recent Stock Ledger Entries filtered by the required item and warehouse.
245
+ - **Accounting** (8) — Chart of Accounts (filterable by `disabled`), Journal
246
+ Entries, and Payment Entries, plus `erpnext_gl_entry_list` (the posted general
247
+ ledger, cancelled entries excluded by default) and `erpnext_financial_report`,
248
+ which runs a standard financial report (Profit and Loss Statement, Balance
249
+ Sheet, General Ledger, Trial Balance…) from a closed allowlist and never
250
+ queues a Prepared Report.
251
+ - **HR** (15) — Employees, Attendance, Leave Applications, Salary Slips, Payroll
252
+ Entries, and Expense Claims, plus attendance repair:
253
+ `erpnext_employee_checkin_list` (the raw punch log, where a day that never
254
+ closed shows up), `erpnext_attendance_day_get` and
255
+ `erpnext_attendance_day_fix`, which add the missing punches and rebuild that
256
+ day's Attendance even when the existing record is already submitted. The last
257
+ two need the `hvg_workspace` app on the site, because the day is recomputed by
258
+ the site's own rule rather than by a copy of it living here.
240
259
  - **Project** (9) — Projects, Tasks (with native assignment), and Timesheets.
241
260
  - **Delivery** (5) — Delivery Notes and Shipments.
242
261
  - **Manufacturing** (7) — BOMs, Work Orders, and Job Cards.
243
262
  - **CRM** (8) — Leads, Opportunities, Contacts, and Campaigns.
244
263
  - **Assets** (8) — Assets, Movements, Maintenance records, and Categories.
245
- - **Operations** (11) — Generic CRUD, native assignment, and file upload for any
264
+ - **Operations** (12) — Generic CRUD, native assignment, and file upload for any
246
265
  DocType (`erpnext_doc_*`, `erpnext_file_upload`), plus `erpnext_method_call`
247
- for allowlisted whitelisted-method calls.
266
+ for allowlisted whitelisted-method calls and `erpnext_calendar_events`, which
267
+ reads a date range the way the ERPNext calendar does so a repeating event
268
+ appears once per occurrence instead of once in total.
248
269
  - **Kanban** (2) — Read-write boards for Task, Opportunity, and Issue with
249
270
  drag-and-drop.
250
271
  - **Analytics** (17) — 11 analytics charts (bar, area, treemap, radar, scatter,
251
272
  P&L…), 5 KPIs with sparklines, and a sales funnel.
252
273
  - **Setup** (3) — Company creation and assignable user listing.
274
+ - **Discovery** (1) — `erpnext_doctype_fields`: the field schema of any DocType
275
+ (name, label, type, link target, mandatory, permlevel), gated on the caller's
276
+ own read permission. Use it instead of inferring a schema from one sample
277
+ document, which only shows the fields that happen to be filled in.
253
278
 
254
279
  Full per-tool reference with parameters: [`docs/tools.md`](docs/tools.md).
255
280
 
@@ -258,12 +283,33 @@ Full per-tool reference with parameters: [`docs/tools.md`](docs/tools.md).
258
283
  | Variable | Required | Description |
259
284
  | -------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
260
285
  | `ERPNEXT_URL` | Yes | ERPNext base URL — self-hosted (e.g. `http://localhost:8000`) or cloud (e.g. `https://mycompany.erpnext.com`) |
261
- | `ERPNEXT_API_KEY` | Yes | API Key from User Settings |
262
- | `ERPNEXT_API_SECRET` | Yes | API Secret from User Settings |
286
+ | `ERPNEXT_API_KEY` | stdio | API Key from User Settings. Over HTTP, leave it unset and let each caller's own token decide who the server acts as (see _Caller identity_) |
287
+ | `ERPNEXT_API_SECRET` | stdio | API Secret from User Settings |
288
+ | `MCP_CALLER_IDENTITY` | No | `required` \| `optional` \| `off`. HTTP only. Defaults to `required` when no API key/secret is set, `off` when they are |
263
289
  | `ERPNEXT_MAX_UPLOAD_BYTES` | No | Maximum decoded file-upload size in bytes (positive integer; default: 10 MiB) |
264
290
  | `ERPNEXT_METHOD_ALLOWLIST` | No | Comma-separated dotted paths or `prefix.*` patterns that `erpnext_method_call` may invoke. Unset means no extra restriction beyond the API key's own ERPNext permissions |
265
291
  | `MCP_MRTR_SIGNING_KEY` | No | Exactly 64 lowercase hex characters; enables signed ambiguous-link elicitation. **Single-instance deployments only** — see below |
266
292
 
293
+ ### Caller identity (HTTP)
294
+
295
+ Over HTTP the server can act **as the user who made the call** instead of under
296
+ one shared ERPNext account. Each tool call forwards that user's own verified
297
+ access token to Frappe as `Authorization: HVGKeycloak <token>`; Frappe resolves
298
+ it to a `User` and applies that user's roles and row-level permissions. Two
299
+ people calling the same tool therefore get different rows, and every write is
300
+ attributed to the person who asked for it.
301
+
302
+ This needs an OAuth/OIDC auth provider (`MCP_OAUTH_JWKS_URL`) whose tokens carry
303
+ an `email` claim, and an ERPNext side that accepts the scheme. `sub` is not
304
+ accepted as a fallback identity: it maps to no ERPNext user, so a deployment
305
+ with the wrong claims fails loudly instead of quietly serving the wrong data.
306
+
307
+ `MCP_CALLER_IDENTITY=required` refuses any call that carries no usable identity.
308
+ `optional` binds the identity when present and otherwise falls back to the
309
+ static API key. `off` is the pre-3.1 behaviour. Under `required` the read cache
310
+ is per caller and the startup cache warm is skipped — there is no user to warm
311
+ it as.
312
+
267
313
  MRTR is opt-in. Without this key, or when the client does not advertise
268
314
  elicitation, ambiguous links keep returning the existing actionable ambiguity
269
315
  error instead of prompting for a selection.