mcp-epicor
Click on "Deploy 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., "@mcp-epicorShow me the details for sales order 12345."
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.
Epicor MCP
Production FastMCP server for Epicor Kinetic. Read-only. There are no write tools and the HTTP client rejects any method other than GET.
Auth follows the same split used by Azure MCP and Atlassian Rovo:
Inbound — the MCP client authenticates to this server (HTTP only).
Outbound — this server authenticates to Kinetic (
X-API-Keyplus Basic or Bearer).
HTTP is fail-closed without MCP_JWKS_URI or MCP_JWT_SECRET.
Author: Clinton Follette.
Tools
Tool | Access | Notes |
| read | Header, |
| read | By |
| read | By |
| read |
|
$select is always applied. The Kinetic Company id is configuration, not a tool argument.
Related MCP server: Generic Database MCP Server
Install (local STDIO)
{
"mcpServers": {
"epicor": {
"command": "mcp-epicor",
"env": {
"EPICOR_BASE_URL": "https://your-server/kinetic",
"EPICOR_COMPANY": "YOURCO",
"EPICOR_API_KEY": "<key>",
"EPICOR_USERNAME": "<user>",
"EPICOR_PASSWORD": "<password>"
}
}
}
}pip install .
mcp-epicorRemote HTTP
export MCP_TRANSPORT=http
export MCP_HOST=127.0.0.1
export MCP_PORT=8002
export MCP_JWKS_URI=https://login.example.com/.well-known/jwks.json
export MCP_JWT_ISSUER=https://login.example.com
export MCP_JWT_AUDIENCE=mcp-epicor
mcp-epicorEndpoint: http://127.0.0.1:8002/mcp. Health: GET /health.
Outbound Kinetic configuration
Variable | Required | Purpose |
| yes | Kinetic origin |
| yes | Path segment in |
| typical |
|
| or bearer | Basic auth |
| optional | Alternative to Basic |
Security
No POST/PATCH/DELETE helpers exist on the client.
HTTP without inbound JWT configuration refuses to boot.
Vendor 401s do not echo credentials.
See SECURITY.md.
License
MIT. Copyright (c) 2026 Clinton Follette.
Available Tools
4 toolsget_customerGet customerBRead-onlyIdempotent
Read a Kinetic customer by CustNum or CustID.
| Name | Required | Description | Default |
|---|---|---|---|
| cust_id | No | Customer CustID. | |
| cust_num | No | Numeric CustNum. |
Output Schema
| Name | Required | Description |
|---|---|---|
| zip | No | |
| city | No | |
| name | No | |
| state | No | |
| cust_id | No | |
| address1 | No | |
| cust_num | No | |
| phone_num | No | |
| credit_hold | No | |
| territory_id | No | |
| email_address | No | |
| sales_rep_code | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and openWorldHint=true, so the safety and idempotency profile is covered. The description adds no behavioral context beyond that — it does not say what happens when both keys are null, when the customer is not found, or whether remote lookups have limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single short sentence with no filler, front-loading the operation and resource. Every word earns its place; nothing is padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values need not be described, and the read-only annotations cover the safety profile; for a trivial two-parameter lookup the definition is nearly sufficient. The only omission is behavior when neither key is supplied, which prevents a full 5.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% (both cust_id and cust_num are documented in the schema), so the baseline is 3. The description merely restates the same two identifiers and adds no format, mutual-exclusion, or precedence detail beyond what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Read'), a specific resource ('Kinetic customer'), and the identifier types used for lookup. It does not explicitly contrast against get_sales_order/get_part/get_shipments, but the distinct resource noun makes selection unambiguous without that.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Implies usage by naming the two lookup keys (CustNum or CustID), from which an agent infers this is a single-customer retrieval tool. However, it offers no explicit when-to-use guidance, no statement of which key to prefer, and no alternatives for lookups by other attributes.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_partGet partBRead-onlyIdempotent
Read a Kinetic part by PartNum.
| Name | Required | Description | Default |
|---|---|---|---|
| part_num | Yes | Epicor PartNum. |
Output Schema
| Name | Required | Description |
|---|---|---|
| ium | No | |
| class_id | No | |
| part_num | Yes | |
| non_stock | No | |
| type_code | No | |
| part_description | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and openWorldHint, so safety and idempotency are covered. The description adds nothing beyond that — no note on behavior when the PartNum does not exist, no auth or rate context, no hint that results come from the live Kinetic/Epicor ERP.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One short, front-loaded sentence with zero filler — the verb and lookup key come first. It is efficient, though bordering on under-specified for anything beyond the basic happy path.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple: one fully documented param, an output schema defining the return shape, and annotations covering safety. Given that structured richness, the description is nearly sufficient, with the only gap being error/not-found behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single parameter is documented as 'Epicor PartNum.' The description names PartNum but adds no format, case-sensitivity, or company/plant scoping detail beyond the schema, so this is the baseline 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Read) and resource (Kinetic part) plus the lookup key (PartNum), so an agent can tell what the tool returns. It does not differentiate from siblings, though the sibling names (get_sales_order, get_customer, get_shipments) target distinct resources so no confusion arises.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no prerequisite or permission note, and no mention of alternatives for retrieving part data. The agent must infer that this is the single-part lookup path from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_sales_orderGet sales orderBRead-onlyIdempotent
Read a Kinetic sales order header, lines, and releases by OrderNum.
| Name | Required | Description | Default |
|---|---|---|---|
| order_num | Yes | Epicor OrderNum. |
Output Schema
| Name | Required | Description |
|---|---|---|
| lines | No | |
| po_num | No | |
| company | No | |
| cust_num | No | |
| order_num | Yes | |
| bt_cust_id | No | |
| open_order | No | |
| order_date | No | |
| order_held | No | |
| void_order | No | |
| bt_cust_num | No | |
| ship_to_num | No | |
| need_by_date | No | |
| request_date | No | |
| currency_code | No | |
| ship_via_code | No | |
| customer_cust_id | No | |
| ship_to_cust_num | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already carry the safety profile (readOnlyHint, idempotentHint true; openWorldHint true), so the bar is lower. The description adds a useful structural note that the read spans header, lines, and releases rather than just the header, but says nothing about auth, rate limits, or lookup failure behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with zero filler; every clause (verb, resource composition, key parameter) earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be re-explained, and the annotations cover the safety/idempotency profile. For a one-parameter read the description is sufficient, with the only shortfall being the absence of usage context relative to sibling getters.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% with a single well-documented required parameter (Epicor OrderNum). 'by OrderNum' merely restates what the schema already provides, adding no format or domain meaning beyond it; baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Read) and a precisely scoped resource (Kinetic sales order header, lines, and releases), keyed by OrderNum. The resource is naturally distinct from siblings get_customer/get_part/get_shipments, though the description never names them explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies a single-record lookup via 'by OrderNum' but gives no when-to-use guidance, no prerequisites, and no routing away from the sibling get_* tools. Nothing tells an agent whether this is the right tool for listing or searching orders versus fetching one by key.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_shipmentsGet shipmentsARead-onlyIdempotent
Read customer shipment pack lines (ShipDtls) for an order. Never writes CustShip.
| Name | Required | Description | Default |
|---|---|---|---|
| order_num | Yes | Epicor OrderNum. |
Output Schema
| Name | Required | Description |
|---|---|---|
| order_num | Yes | |
| shipments | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and openWorldHint=true, so the safety profile is covered. The description reinforces this with "Never writes CustShip" and names the table it reads, which adds entity-level detail beyond the annotations. It still says nothing about permissions, volume, or result shape.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with the operation and resource, followed by the write-safety guarantee. Nothing is padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values need no explanation, and the single required parameter is fully documented in the schema. The description covers what is read, the scope, and the read-only guarantee, leaving only minor gaps such as ordering/pagination behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is a single required parameter with 100% schema description coverage ("Epicor OrderNum."), so the schema already carries the semantics. The description corroborates that the read is scoped "for an order" but adds no format or boundary detail beyond that.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: read customer shipment pack lines (ShipDtls) for an order. The underlying entity is named concretely (ShipDtls), which is more precise than the title alone. It does not explicitly contrast with siblings like get_sales_order, but the resource is unambiguous enough to keep them apart.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
"For an order" implies the tool is used when you have an order number and need its shipment lines, which is reasonable context. However, there is no explicit when-to-use/when-not-to-use guidance and no mention of alternatives, so the agent must infer the routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
4 tool updates
v0.1.0- First observed
get_customer - First observed
get_part - First observed
get_sales_order - First observed
get_shipments
TDQS
Scored across 4 tools
Each tool targets a distinct entity (sales order, customer, part, shipments), and descriptions clarify their purposes. get_shipments could be confused with get_sales_order since it retrieves order-related data, but the description explicitly distinguishes it as shipment pack lines.
All tools follow a consistent get_ + noun snake_case pattern, making them predictable and easy to distinguish.
Four tools is borderline thin for an ERP integration like Epicor Kinetic. While each tool is well-scoped, the set covers only a small fraction of typical ERP operations, suggesting under-scoping.
The surface is read-only with no create, update, delete, or list operations for any entity. This creates significant gaps for an agent that needs to perform common ERP tasks beyond fetching individual records.
Maintenance
Related MCP Connectors
중소 제조기업용 ERP 조회 전용 MCP 서버(재고·매출·채권·수주/발주·회계). 쓰기 도구 없음.
- dataOAuthco.thinair
Read-only PostgreSQL, MySQL, SQL Server access via MCP — 24 dialect-aware hosted tools.
Read-only MCP access to a documented IT fleet: state, changes, posture. 15 tools.
Query your org's data in natural language — read-only MCP access to SQL, NoSQL, files & warehouses.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceThis project builds a read-only MCP server. For full read, write, update, delete, and action capabilities and a simplified setup, check out our free CData MCP Server for Epicor Kinetic (beta): https://www.cdata.com/download/download.aspx?sku=UEZK-V&type=beta3MIT
- FlicenseNot gradedqualityDmaintenanceEnables read-only SQL querying and schema inspection across MSSQL, PostgreSQL, and MySQL databases via MCP tools.-
- FlicenseNot gradedqualityCmaintenanceEnables querying Proluxe ERP data such as customers, orders, invoices, AR aging, bills of materials, product catalog, focus priorities, and projects through MCP tools.-
- FlicenseNot gradedqualityBmaintenanceEnables secure, read-only querying of only predefined logical database views through MCP tools and a REST API, using validated SQL and semantic view metadata.-