Acumatica MCP Server
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| ACUMATICA_COMPANY | Yes | The Acumatica company name. | |
| ACUMATICA_BASE_URL | Yes | The base URL of your Acumatica instance. | |
| ACUMATICA_PASSWORD | Yes | The service account password. | |
| ACUMATICA_USERNAME | Yes | The service account username. | |
| ACUMATICA_ALLOW_WRITES | No | Set to '1' to enable upsert_record and invoke_action tools. | 0 |
| ACUMATICA_ALLOW_DELETES | No | Set to '1' to enable delete_record tool. | 0 |
| ACUMATICA_ENDPOINT_PATH | Yes | The endpoint path to the contract-based REST API (e.g., /entity/Default/24.200.001). |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| list_entitiesA | List the Acumatica entities exposed by this tenant's OpenAPI spec. Args: filter: Optional case-insensitive substring to narrow the list, e.g. "order" returns SalesOrder, PurchaseOrder, etc. Returns: {count, entities: [{name, actions}]} Tip: call describe_entity(name) to get the full field list, key format, and expandable sub-collections for any entity before querying it. |
| describe_entityA | Return the full metadata for an entity: fields, key format, actions, and sub-collections. Always call this before list_records or get_record when you are unsure of:
Args: entity: Entity name, e.g. "SalesOrder", "Bill", "Customer". Returns one of two shapes: Normal entity (has a key): { "entity": "SalesOrder", "fields": ["OrderType", "OrderNbr", "CustomerID", ...], # valid $select / $filter names "key_fields": ["OrderType", "OrderNbr"], # fields that make up the URL key "key_format": "Slash-separated: /", # how to build the id= string "actions": ["CancelSalesOrder", ...], "expand": ["Details", "Shipments", ...] } Query-only entity (inquiry/summary view - no addressable key): { "entity": "AccountSummaryInquiry", "query_only": true, "note": "This entity has no addressable key - use list_records with filter= only. ...", "fields": [...], "actions": [], "expand": [] } For query-only entities: do NOT call get_record - pass at least one filter= to list_records. Calling list_records with no filter on these entities returns HTTP 500 on this tenant. Returns {error: "Unknown entity"} if the entity is not in the catalog. Examples: describe_entity("SalesOrder") # -> key_format: "Slash-separated: /" # -> use get_record("SalesOrder", "QT/I004264") |
| list_recordsA | Retrieve records from an Acumatica entity using OData query parameters. IMPORTANT: Call describe_entity(entity) first to get the exact field names for this entity. Using a field name that doesn't exist causes a hard 500 error. Args: entity: Entity name, e.g. "SalesOrder", "Bill", "Customer". filter: OData $filter expression, e.g. "Status eq 'Open'". Only use field names returned by describe_entity() - guessed names cause KeyNotFoundException (500). Date/time fields require datetimeoffset literal format: Date gt datetimeoffset'2026-05-01T00:00:00-04:00' Plain strings or datetime'' literals will fail. top: Max rows to return. Defaults to 50; use a smaller number when exploring. skip: Rows to skip (pagination). select: Comma-separated fields, e.g. "OrderNbr,CustomerID,OrderTotal". Only use field names returned by describe_entity() - invalid names -> 500. expand: Comma-separated sub-collections to inline, e.g. "Details,Shipments". Valid values are listed in describe_entity() under 'expand'. orderby: e.g. "Date desc". NOTE: $orderby is silently ignored by this tenant. To get the most recent records, use a date filter instead and sort client-side. Use a narrow window first - expand only if empty: Step 1: filter="Date gt datetimeoffset'T00:00:00-04:00'" Step 2: if empty, retry with today-30d, then today-90d Client-side: sort results by Date desc, then LastModifiedDateTime desc to find the single most-recent record. This resolves "last created" queries in 1-2 API calls instead of 5+. custom: Pull user-defined (DAC extension) fields not in the standard contract. Format: "ViewName.FieldName" - multiple fields comma-separated. Example: "Document.LastModifiedByID,Document.CreatedByID" To discover available view names and fields, call get_schema(entity). Common view name for header-level fields: "Document". Returns:
{status, ok, data: [records]} or {status, ok: false, error}
Each record includes a |
| get_recordA | Get a single record by its key. Call describe_entity(entity) first to find the key_fields and key_format for this entity - the key format varies per entity and using the wrong format causes a 500 error. Args: entity: Entity name. id: The record key - key field values joined with '/' in key order. Examples: SalesOrder -> "QT/I004264" (OrderType/OrderNbr) Bill -> "Bill/001234" (Type/ReferenceNbr) Customer -> "C000001" (CustomerID only) Invoice -> "INV/001234" (Type/ReferenceNbr) Use describe_entity() to find the exact key_fields for any entity. A GUID (the session 'id' field) also works if you have it. select / expand / custom: same as list_records. Returns:
{status, ok, data: {record}} or {status, ok: false, error}
Record includes a |
| upsert_recordA | Create or update a record (PUT /{Entity}). Requires ACUMATICA_ALLOW_WRITES=1. Acumatica's contract-based API uses PUT for both create and update - the server decides based on whether key fields match an existing record. Args:
entity: Entity name.
data: Body in Acumatica's |
| delete_recordA | Delete a record by ID or key fields. Requires ACUMATICA_ALLOW_DELETES=1. |
| invoke_actionA | Invoke a named action on an entity (POST /{Entity}/{Action}). Requires ACUMATICA_ALLOW_WRITES=1. Examples: invoke_action("SalesOrder", "CancelSalesOrder", entity_record={"OrderType": {"value": "SO"}, "OrderNbr": {"value": "SO012345"}}) invoke_action("Bill", "ReleaseBill", entity_record={"ReferenceNbr": {"value": "001234"}}) Args: entity: Entity name. action: Action name (call describe_entity(entity) to see available actions). entity_record: The record the action runs against, in Acumatica's wrapped format. parameters: Action-specific parameters, if any. Returns 204 No Content for fire-and-forget actions; 202 for long-running. |
| get_schemaA | Return the entity's extension-field schema (GET /{Entity}/$adHocSchema). Two reasons to call this:
Common SalesOrder view names (confirmed working): Document - SOOrder header fields (CreatedByID, BranchID, etc.) CurrentDocument - additional header computed fields Transactions - line-level fields (on Details rows) Adjustments - payment application fields Example workflow: 1. get_schema("SalesOrder") # identify view names 2. list_records("SalesOrder", # pull extension + standard DAC fields custom="Document.CreatedByID,Document.UsrYourCustomField") |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
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/yourlastnamesoundslikeatypeofpasta/acumatica-mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server