leo-proluxe-mcp
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@leo-proluxe-mcpFind customer Acme and show their open invoices."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
leo-proluxe-mcp
Proluxe ERP as a Leo package, over MCP — customers, orders, invoices, AR aging, bills of materials, the product catalog, focus priorities and projects, from the Proluxe API gateway.
The same integration as the compiled leo-proluxe package, reachable as a
package the hub installs at runtime rather than one it has to be rebuilt
for.
Tools
The compiled package exposed one proluxe tool with a fifteen-value action
enum and a nine-field union schema. MCP names tools, so each action is its own
tool with only its own parameters — the same fifteen names, the same paths.
Tool | Requires | Upstream |
|
|
|
|
|
|
| — |
|
| — |
|
| — |
|
| — |
|
| — |
|
| — |
|
|
|
|
|
|
|
|
|
|
| — |
|
| — |
|
| — |
|
| — |
|
Everything downstream keys on the 18-character Salesforce id, so find_customer
comes first and its id goes into find_orders and find_invoices.
bom_inspect is two requests when it has to be: the MRP service keeps some
parts under a Main_ prefix and some not, and which is which is not knowable
from the part number. The bare form is tried first, the prefix is the fallback,
and a failure names both — "SL1266TBAU not found" would send you looking for
a part that is right there under a name nobody mentioned.
project_cards branches on absence: with a project id you get that project's
cards, without one you get every card. A blank id is an absent one.
Responses are forwarded as the upstream JSON text, unparsed.
Related MCP server: odoo-mcp-server
Authentication
An Auth0 machine-to-machine client-credentials grant. This server POSTs
client_id, client_secret, audience and grant_type=client_credentials to
https://{domain}/oauth/token, then sends the token as Authorization: Bearer
alongside X-User-Email, which is what scopes user-facing requests.
The token is cached and reused for the lifetime Auth0 reports, minus five minutes so none expires in flight. If the gateway answers 401 or 403 the cached token is dropped and the request is retried exactly once with a fresh one — without that, a token that dies early (rotated secret, revoked grant, clock skew) wedges every Proluxe call until the process restarts; with more than one, a genuinely bad credential becomes an unbounded stream of token requests. A second refusal says the credentials and audience are the thing to look at.
Configuration
Six settings. Leo hands them to this process under their settings keys,
verbatim and lower-case, so the descriptor's settings_read and
process.env.<key> have to agree or the credential silently never arrives.
Key | |
| required — the gateway base URL |
| required — from a machine-to-machine app |
| required |
| required — scopes user-facing requests |
| optional, defaults to |
| optional, defaults to |
Without the four required ones the server still starts and lists its tools; every call answers with the missing keys named and where to enter them.
Development
npm install
node test.js # no network neededThe test covers what fails quietly, with an injected fetch and an injected
clock:
The token body. Omit
audienceand Auth0 returns a 200 with a real but opaque token, which the gateway then declines — that reads as a wrong secret.clientIdforclient_idis not a malformed request, it is a request with no client id.The cache and its arithmetic. That one token serves many calls; that it expires when Auth0 said it would; that an unreported
expires_infalls back to an hour rather than to forever; that a lifetime shorter than the buffer floors instead of re-minting on every call.A bad token, told apart from an empty result. 401/403 retries once and only once, 500 is not retried at all, an Auth0 refusal and a 200 with no
access_tokenboth raise rather than return nothing. Every one of these otherwise arrives as an empty page, indistinguishable from a customer who has no invoices.Path and query building. Absent stays absent — an undeclared filter interpolated into a URL is the literal text
undefined, which the gateway honours as a real customer id. Empty means no?at all;limitis read as the Rust read it (as_u64, so the string"200"silently falls back); the per-action defaults are pinned;/escapes, so an id cannot walk sideways into another endpoint.The
Main_fallback, driven both ways round — a retry that re-requested the bare path would pass on every part that already worked and fail on exactly the parts the fallback exists for.
Faithfulness notes
Two places where this is deliberately not a byte-for-byte port:
Non-ASCII percent-encoding. The Rust wrote
%{:02X}of the code point, soéwent out as Latin-1%E9and€as the malformed five-character%20AC. Here it is UTF-8. ASCII — which is all a Salesforce id or a part number contains — is byte-identical, including+for a space in path segments as well as query values, which is the Rust's spelling and the one the gateway has been answering.A non-string required argument. The Rust's
require_str!refused a numericquery; here the schema asks for a string and a number is stringified, matching the reference servers.
Publishing
./store/publish.sh # live
./store/publish.sh draft # stage for review at admin.leoconnect.ioNeeds a Cloudflare login with D1:Edit on the leo-store database. The script
refuses unless the pinned commit is both real and pushed — a SHA that resolves
nowhere installs cleanly and then fails on every hub at first launch.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceEnables interaction with Odoo ERP systems for product, customer, order, invoice, and payment management using MCP tools.5MIT
- FlicenseNot gradedqualityDmaintenanceEnables querying ERP data via an external API with adaptive caching, and accessing data from Google Sheets or local Excel/CSV files through dual MCP endpoints.
- FlicenseNot gradedqualityCmaintenanceGoverned MCP bridge that lets AI clients query live ERP data via SuiteQL, saved searches, and records, with role-based permissions and full audit logging.
Related MCP Connectors
Provide seamless access to Appfolio Property Manager Reporting API through a standardized MCP serv…
QuickBooks MCP Pack — query customers, invoices, and accounts via QuickBooks Online API.
A paid remote MCP for AI SDK data query MCP, built to return verdicts, receipts, usage logs, and aud
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/TheBananaStand/leo-proluxe-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server