Install
$ agentstack add mcp-hallboys-mcp4acumatica Open-source listing, not yet scanned by AgentStack. Follow the source repository for install instructions.
Security review
⚠ Flagged1 finding(s); flagged for manual review. · v0.1.0 How review works →
- • Prompt-injection patterns
- • Secret / credential exfiltration
- • Dangerous shell & filesystem operations
- • Untrusted network calls
- • Known-malicious package signatures
- high Pipes remote content directly into a shell (remote code execution).
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
MCP4Acumatica
> Disclaimer: This project is an independent, community-built integration and is not affiliated with, endorsed by, or supported by Acumatica, Inc. "Acumatica" is a registered trademark of Acumatica, Inc. Use of the Acumatica name and API is for interoperability purposes only.
A remote Model Context Protocol (MCP) server that connects Claude to Acumatica ERP 2025 R2. Runs on Cloudflare Workers with per-user OAuth authentication against your Acumatica instance.
Each user authenticates with their own Acumatica credentials. Their Acumatica role controls which records they can access. The MCP server additionally requires a specific Acumatica role for access, shows a consent interstitial, and automatically redacts sensitive fields before data reaches the AI model.
Features
- 48 tools -- 38 read-only lookups + 6 utility/discovery + 4 schema-knowledge tools (see [Available Tools](#available-tools))
- Per-user OAuth -- users log in with their Acumatica credentials (or SSO)
- Role-based access -- Acumatica's security model governs what each user sees
- Role gate -- only users with a designated Acumatica role (e.g.,
MCP Access) can connect - Consent interstitial -- users must acknowledge AI data processing before accessing tools
- Sensitive field redaction -- SSN, bank accounts, salary, and other PII fields are automatically redacted before data leaves the server
- Rate limiting -- 3 concurrent requests, 40 requests/minute per user
- Pagination refusal -- list/query tools return a structured
{ truncated, paginationSupported: false, actionRequired }envelope when results hit the record cap, instructing the AI to ask the user for a narrower filter rather than calling the tool again - Structured audit logging -- all tool invocations, auth events, and field redactions are logged
- Admin console -- web-based admin interface at
/docs/adminfor viewing logs and managing runtime settings without redeploying - Long-term log retention -- R2-backed log storage via Cloudflare Logpush with searchable log viewer
Architecture
Claude (claude.ai / Desktop / API)
|
v MCP over streamable-http
+----------------------------------+
| Cloudflare Worker |
| OAuth 2.1 Provider |
| /authorize -> Acumatica login |
| /callback AI data consent |
| /token, /register (DCR) |
| /mcp -> McpAgent DO (48 tools)|
+---------------+------------------+
| Bearer token (per-user)
v
Acumatica 25R2 SaaS
Contract-Based REST API
Default/25.200.001
Prerequisites
- Node.js >= 18
- A Cloudflare account (Workers paid plan for Durable Objects)
- An Acumatica 2025 R2 instance with:
- A Connected Application configured in SM303010 with the Authorization Code OAuth 2.0 flow (scopes are sent by the server in the request, not configured on the app)
- A redirect URI pointing to your worker's
/callbackendpoint - An
MCP Accessrole (SM201005) -- a marker role with no permissions required - An
MCPAccessGeneric Inquiry (SM208000) -- a trivial GI assigned only to theMCP Accessrole, with Expose via OData enabled (see [Architecture docs](docs/architecture.md) for details)
Setup
There are three install paths. All three rely on the same Acumatica-side prerequisites — finish those first (see "[Acumatica-side configuration](#acumatica-side-configuration)" below) regardless of which path you pick.
| Path | Best for | Terminal needed? | |------|----------|------------------| | A. Deploy to Cloudflare button | Adopters who want a fully GUI install | No | | B. One-line installer | Developers who already have git / node / npm | Yes (one command) | | C. Manual setup | Anyone who wants to inspect each step | Yes |
Path A — Deploy to Cloudflare button (no terminal)
[](https://deploy.workers.cloudflare.com/?url=https://github.com/hallboys/MCP4Acumatica)
The button forks this repo to your GitHub account, reads wrangler.jsonc, auto-creates the KV namespace and R2 bucket, prompts for secrets, and deploys. Step-by-step:
- Click the button. Cloudflare will ask you to sign in (or create an account) and authorize a GitHub fork.
- Confirm bindings. You'll be prompted to create KV namespaces twice — once for the
TOKEN_STOREbinding (app data: tokens, OAuth state, cache, config, admin sessions) and once forOAUTH_KV(used internally by the OAuth library). This is expected: they're two separate bindings and never share keys.
> ⚠️ Give the two namespaces different names (e.g. mcp4acumatica-app for TOKEN_STORE and mcp4acumatica-oauth for OAUTH_KV). Cloudflare auto-provisioning derives the default title from the Worker name, so both fields default to mcp4acumatica — and creating two namespaces with the same title fails with "Cannot provision a KV Namespace with the title … because it already exists." If you already hit that error, a half-finished namespace was left behind: go to Storage & Databases → KV and delete the orphaned mcp4acumatica namespace, then retry with two distinct names. (Cloudflare's GUI auto-provisioning can't point both bindings at one namespace, and config can't pre-set distinct titles — so two separate namespaces with distinct names is the way. If the GUI keeps failing, use a terminal install path below: setup.sh creates one namespace and binds both to it.)
The R2 buckets (mcp4acumatica-logs, mcp4acumatica-index) are created the same way, but their names are fixed in wrangler.jsonc so they don't collide.
- Set secrets. When prompted, paste:
ACUMATICA_CLIENT_ID— from your Connected Application (SM303010)ACUMATICA_CLIENT_SECRET— from the same screenCOOKIE_ENCRYPTION_KEY— open your browser console on any page and run:
``js [...crypto.getRandomValues(new Uint8Array(32))].map(b => b.toString(16).padStart(2,'0')).join('') `` Copy the resulting 64-character hex string.
ADMIN_SECRET— any password you'll remember (protects the/docs/adminconsole). Generate one with[...crypto.getRandomValues(new Uint8Array(24))].map(b => b.toString(16).padStart(2,'0')).join('')if you don't have a preference.
- Deploy. Cloudflare connects the fork to Workers Builds and pushes the first deployment.
- Update the Acumatica vars. After the deploy completes, open
Workers & Pages → mcp4acumatica → Settings → Variables and Secretsin the Cloudflare dashboard and edit:
ACUMATICA_URL(e.g.https://yourcompany.acumatica.com)ACUMATICA_TENANT(your login company)- Optionally
ACUMATICA_MAX_RECORDS,ACUMATICA_MCP_ROLE,REDACT_PATTERNS,REDACT_SKIP
Click Save and Deploy — Cloudflare redeploys with the new values.
- Add a redirect URI to your Connected Application. Your worker is now reachable at
https://mcp4acumatica..workers.dev. Addhttps:///callbackto the redirect URIs in Acumatica's SM303010 screen. (To use a custom domain instead, see "[Custom domain](#custom-domain-optional)" below.) - Test the deploy. Visit
https:///docs/admin/preflight, log in with yourADMIN_SECRET, and run the preflight diagnostic. It probes Acumatica connectivity, the OIDC discovery endpoint, the Connected App credentials, the tenant path, and the contract API version — any misconfiguration is called out by name.
After this point Claude can connect (see "[Connecting Claude](#connecting-claude)" below).
Path B — One-line installer (terminal)
If you already have git, node, and npm, run:
curl -fsSL https://mcp4acumatica.hallboys.com/install.sh | bash
This clones the repo, installs dependencies, and runs ./setup.sh. The setup script prompts for the Acumatica values you must supply (URL, tenant, Connected App client ID and secret), auto-generates the crypto secrets, creates the KV namespace and R2 bucket, uploads secrets, deploys, and then runs the preflight check.
If you prefer to inspect the script first:
curl -fsSL https://mcp4acumatica.hallboys.com/install.sh -o install.sh
less install.sh # read it
bash install.sh # then run
Path C — Manual setup (terminal)
1. Clone and install
git clone https://github.com/hallboys/MCP4Acumatica.git
cd MCP4Acumatica
npm install
2. Create KV namespace
npx wrangler kv namespace create TOKEN_STORE
Note the namespace ID from the output — you'll paste it into wrangler.jsonc next. The same ID is used for both the TOKEN_STORE and OAUTH_KV bindings.
3. Configure wrangler
wrangler.jsonc is tracked in the repo as the deploy template. Edit it in place and fill in:
- The KV namespace ID from step 2 (both
TOKEN_STOREandOAUTH_KVbindings — same id) ACUMATICA_URL— your Acumatica instance URL (e.g.https://yourcompany.acumatica.com)ACUMATICA_TENANT— your Acumatica company/tenant name
To keep your local values out of git status (so you can still pull updates without conflicts):
git update-index --skip-worktree wrangler.jsonc
4. Set secrets
npx wrangler secret put ACUMATICA_CLIENT_ID
npx wrangler secret put ACUMATICA_CLIENT_SECRET
npx wrangler secret put COOKIE_ENCRYPTION_KEY # use `openssl rand -hex 32`
npx wrangler secret put ADMIN_SECRET # any password — protects /docs/admin
5. Deploy
npx wrangler deploy
6. Local development (optional)
cp .dev.vars.example .dev.vars
# Edit .dev.vars with your Acumatica credentials
npx wrangler dev
Acumatica-side configuration
These steps are required regardless of which install path you pick. They can't be automated — Acumatica's API doesn't expose them.
Connected Application (SM303010)
- In Acumatica: System > Integration > Connected Applications (SM303010).
- Create a new Connected Application.
- Set the OAuth 2.0 Flow to Authorization Code.
- Add a redirect URI:
https:///callback(use the*.workers.devhostname or your custom domain). - Note the Client ID and Client Secret — you'll provide these as secrets during deploy.
> There is no scope field to configure here. OAuth scopes (api openid profile email offline_access, including the offline_access that makes Acumatica issue refresh tokens) are sent by the MCP server in the authorization request — they aren't set on the Connected Application.
Role and Generic Inquiry (SM201005, SM208000)
The MCP server requires users to have a specific Acumatica role before they can access AI tools. This is enforced via a canary Generic Inquiry (GI) that is assigned only to that role.
- Create role: System > Access Rights > User Roles (SM201005) → create a role named
MCP Access. No screen permissions are needed — it's purely a marker role. - Create Generic Inquiry: System > Customization > Generic Inquiry (SM208000) → create a GI named
MCPAccesswith any trivial query (a single column from any table is fine). Assign it only to theMCP Accessrole. Enable Expose via OData. - Assign role to users: Assign the
MCP Accessrole to each Acumatica user who should have AI assistant access.
> The role name is configurable via the ACUMATICA_MCP_ROLE variable. Edit it in the Cloudflare dashboard (Variables and Secrets) or in wrangler.jsonc.
Generic Inquiry exposure to AI (strongly recommended)
A mature Acumatica instance can have hundreds of Generic Inquiries, most built for human screens (wide report grids, dashboards, ad-hoc queries). Exposing all of them to the assistant floods its context and makes it pick the wrong inquiry — and, worse, a parameterized GI exposed via OData returns silently wrong data: queried without its parameters, Acumatica returns default/unfiltered rows with no error, which the model cannot detect. The GI exposure gate flips this to opt-in: you tag the GIs that are genuinely useful and correct for an AI agent to query (ExposedToMCP), and the model sees only those.
The gate is inactive until you configure it — the server runs, but with no registry the assistant cannot discover GIs (acumatica_list_generic_inquiries returns nothing; a user can still run a GI by exact name). Configuring it gives the assistant a curated set it can safely discover. Enabling it is a one-time Acumatica customization project — bundled in [acumatica/](acumatica/), it adds the custom fields UsrExposedToMCP / UsrAIDescription (GIDesign) and UsrResAIDescription (GIResult) plus the SM208000 form changes — followed by the MCPGIs / MCPGIFields feed GIs, read access on the feeds for the MCP Access role, and tagging the GIs you want exposed. See [docs/generic-inquiries.md](docs/generic-inquiries.md).
> See [Generic Inquiries](docs/generic-inquiries.md) for the full rationale, how to decide which GIs to expose, and step-by-step setup.
Custom domain (optional)
The deploy gives you a *.workers.dev hostname out of the box. To attach a branded hostname:
- Via the Cloudflare dashboard:
Workers & Pages → mcp4acumatica → Settings → Domains & Routes → Add. The domain's zone must be on your Cloudflare account. - Via
wrangler.jsonc: uncomment theroutesblock at the top of the file, editpatternandzone_name, redeploy.
If you change hostnames, remember to add the new https:///callback to your Connected Application's redirect URIs in SM303010.
Connecting Claude
Claude.ai / Claude Desktop
- Go to Settings > Connectors
- Click Add Connector and enter the URL:
https:///mcp - On first use, you'll be redirected to your Acumatica login page
- If your account has the
MCP Accessrole, you'll see a consent page explaining AI data processing - After acknowledging consent, Claude will have access to all 48 tools
Claude Code (CLI)
claude mcp add acumatica-erp --transport streamable-http https:///mcp
API (via Anthropic SDK)
When using the Anthropic API with MCP, point the MCP client to https:///mcp. The server supports OAuth 2.1 with Dynamic Client Registration at /register.
Available Tools
Core
| Tool | Description | |------|-------------| | acumatica_get_customer | Customer record with contacts, credit rules, balance | | acumatica_get_vendor | Vendor record with contacts, terms, tax info | | acumatica_get_sales_order | Sales order with line items, totals, shipping |
Financial / Accounting
| Tool | Description | |------|-------------| | acumatica_get_invoice | AR invoice with line items and tax details | | acumatica_get_bill | AP bill with line items and PO linkage | | acumatica_get_journal_transaction | GL journal batch with debit/credit details | | acumatica_get_payment | AR payment with applied documents and orders | | acumatica_get_account | GL chart of accounts lookup | | acumatica_get_check | AP check/vendor payment with history |
Inventory & Warehouse
| Tool | Description | |------|-------------| | acumatica_get_stock_item | Stock item with pricing, warehouse qty, vendors | | acumatica_get_non_stock_item | Non-stock item (service, labor, expense) | | acumatica_get_inventory_quantity_available | Real-time available quantity across warehouses | | acumatica_get_inventory_summary | Aggregated inventory balances by warehouse | | acumatica_get_warehouse | Warehouse with locations and settings | | acumatica_get_item_class | Item classification defaults |
Purchasing
| Tool | Description | |------|-------------| | acumatica_get_purchase_order | PO with line items, vendor, totals | | acumatica_get_purchase_receipt | Receipt with received qty and PO linkage |
Projects
| Tool | Description |
…
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: hallboys
- Source: hallboys/MCP4Acumatica
- License: Apache-2.0
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.