Python MCP tool for D365 Commerce Scale Unit REST APIs
Project description
d365-csu
Python MCP tool for D365 Commerce Scale Unit (CSU) REST APIs.
Provides CRUD operations against CSU endpoints and a built-in catalog of available endpoints with sample JSON payloads.
Installation
pip install -e .
Configuration
Set the following environment variables:
| Variable | Description |
|---|---|
CSU_BASE_URL |
CSU base URL (e.g. https://myhost.commerce.dynamics.com/Commerce) |
CSU_OUN |
Operating Unit Number |
AZURE_TENANT_ID |
Azure AD tenant ID |
AZURE_CLIENT_ID |
App registration client ID |
AZURE_CLIENT_SECRET |
App registration client secret |
AZURE_RESOURCE_ID |
CSU resource ID for token scope |
Usage
As an MCP Tool
Add to your MCP client config (e.g. Claude Desktop):
{
"mcpServers": {
"d365-csu": {
"command": "d365-csu",
"env": {
"CSU_BASE_URL": "https://myhost.commerce.dynamics.com/Commerce",
"CSU_OUN": "128",
"AZURE_TENANT_ID": "your-tenant-id",
"AZURE_CLIENT_ID": "your-client-id",
"AZURE_CLIENT_SECRET": "your-client-secret",
"AZURE_RESOURCE_ID": "your-resource-id"
}
}
}
}
Browse Endpoints (no credentials needed)
from d365_csu.endpoints import list_endpoints, get_sample_payload, list_entities
# List all supported entities
print(list_entities())
# ['Carts', 'Categories', 'Customers', 'OrgUnits', 'Products', 'SalesOrders']
# List all endpoints for an entity
for ep in list_endpoints("Customers"):
print(f"{ep['method']} {ep['path']} — {ep['description']}")
# Get a sample request body
payload = get_sample_payload("Customers", "Search")
print(payload)
Direct Python Usage
from d365_csu.auth import AzureADAuth
from d365_csu.client import CSUClient
from d365_csu.entities import customers, products
auth = AzureADAuth(
tenant_id="...",
client_id="...",
client_secret="...",
resource_id="...",
)
client = CSUClient("https://myhost.commerce.dynamics.com/Commerce", "128", auth)
# Search customers
results = customers.search_customers(client, "contoso")
# Search products
results = products.search_products(client, "laptop")
Available MCP Tools
| Tool | Description |
|---|---|
csu_list_endpoints |
List available CSU endpoints with sample payloads |
csu_list_entities |
List supported entity names |
csu_get_sample_payload |
Get sample JSON body for an endpoint |
csu_search_customers |
Search customers by keyword |
csu_create_customer |
Create a new customer |
csu_search_products |
Search product catalog |
csu_get_product |
Get a product by ID |
csu_manage_cart |
Cart operations (create, add lines, checkout) |
csu_search_orders |
Search sales orders |
csu_get_stores |
Get org units / stores |
csu_get_categories |
Get category hierarchy |
csu_raw_request |
Make a raw CSU API call |
Usage with Claude CLI
Add d365-csu as an MCP server in your project's .claude/settings.json:
{
"mcpServers": {
"d365-csu": {
"command": "d365-csu",
"env": {
"CSU_BASE_URL": "https://myhost.commerce.dynamics.com/Commerce",
"CSU_OUN": "128",
"AZURE_TENANT_ID": "your-tenant-id",
"AZURE_CLIENT_ID": "your-client-id",
"AZURE_CLIENT_SECRET": "your-client-secret",
"AZURE_RESOURCE_ID": "your-resource-id"
}
}
}
}
Once configured, Claude CLI can call any of the MCP tools directly. For example:
> Search for customers named "contoso"
Claude will call: csu_search_customers(keyword="contoso")
> Create a cart, add product 12345, and checkout
Claude will call: csu_manage_cart(action="create"), then add_line, then checkout
You can also add the config to ~/.claude/settings.json to make it available globally across all projects.
Usage with GitHub Copilot CLI
GitHub Copilot CLI does not currently support MCP servers. To use d365-csu with Copilot, use it as a Python library directly:
pip install d365-csu
python -c "from d365_csu.entities import customers; ..."
For VS Code with GitHub Copilot Chat, MCP server support may be available via the VS Code MCP extension. Configure it the same way as Claude Desktop (see As an MCP Tool above).
Architecture / Sequence Diagrams
Full diagrams are available in docs/sequence-diagrams.md. Key flows shown below.
Authentication Flow
sequenceDiagram
participant App
participant AzureADAuth
participant AzureAD as Azure AD
participant CSUClient
App->>AzureADAuth: AzureADAuth(tenant_id, client_id, client_secret, resource_id)
App->>CSUClient: CSUClient(base_url, oun, auth)
App->>CSUClient: client.get("/some/path")
CSUClient->>AzureADAuth: get_headers(oun)
AzureADAuth->>AzureAD: acquire_token_for_client(scopes)
AzureAD-->>AzureADAuth: access_token
AzureADAuth-->>CSUClient: {Authorization: Bearer <token>, OUN}
CSUClient->>CSUClient: HTTP request with headers
Cart to Checkout
sequenceDiagram
participant App
participant CSUClient
participant CSU as CSU API
App->>CSUClient: create_empty_cart(client)
CSUClient->>CSU: POST /Carts/CreateEmptyCart
CSU-->>CSUClient: {Id: "cart-123"}
CSUClient-->>App: cart object
App->>CSUClient: add_cart_lines(client, "cart-123", lines)
CSUClient->>CSU: POST /Carts('cart-123')/AddCartLines
CSU-->>CSUClient: updated cart
CSUClient-->>App: cart with lines
App->>CSUClient: checkout(client, "cart-123")
CSUClient->>CSU: POST /Carts('cart-123')/Checkout
CSU-->>CSUClient: {SalesOrder}
CSUClient-->>App: sales order
MCP Tool Call (End-to-End)
sequenceDiagram
participant Claude as AI Assistant
participant MCP as MCP Server
participant Auth as AzureADAuth
participant AzureAD as Azure AD
participant CSUClient
participant CSU as CSU API
Claude->>MCP: csu_search_customers(keyword="contoso")
MCP->>MCP: _get_client() reads env vars
MCP->>Auth: AzureADAuth(...)
MCP->>CSUClient: CSUClient(base_url, oun, auth)
MCP->>CSUClient: search_customers(client, "contoso")
CSUClient->>Auth: get_headers(oun)
Auth->>AzureAD: acquire_token_for_client(scopes)
AzureAD-->>Auth: access_token
Auth-->>CSUClient: headers
CSUClient->>CSU: POST /Customers/Search
CSU-->>CSUClient: {value: [...]}
CSUClient-->>MCP: results
MCP-->>Claude: JSON response
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file d365_csu-0.1.1.tar.gz.
File metadata
- Download URL: d365_csu-0.1.1.tar.gz
- Upload date:
- Size: 12.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1a6939514160d25cecb03f452f5f940e779faeba17a9e580a8304fe97fb8f8ae
|
|
| MD5 |
fdd6236fa76c0014c3ec58193f2770de
|
|
| BLAKE2b-256 |
f4e1c7da77785f67273d8188e165e60ade59e3f3b5ee938d25a4812cd9cd563f
|
File details
Details for the file d365_csu-0.1.1-py3-none-any.whl.
File metadata
- Download URL: d365_csu-0.1.1-py3-none-any.whl
- Upload date:
- Size: 14.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e493aefcea5b2f0e34daf4da35059c2dcc3fc03b7e39a12958de71e147673082
|
|
| MD5 |
fc2a3164b699e4c15a79d8271a0c2e10
|
|
| BLAKE2b-256 |
944dbe555ef88b79a76d6e0d43065dc9312f8fb7aa11d2541669ce6fa669bd11
|