D365 F&O Client & MCP Server v0.3.7: Request Tracing & Server Timing Are Here
If you've ever spent hours digging through D365 Finance & Operations logs trying to correlate a failed API call with a cryptic error message — this release is for you.
Version 0.3.7 of the d365fo-client Python library and its companion MCP Server lands today with two headline features: comprehensive request tracing and server timing visibility. Together they transform debugging from a guessing game into a precise, data-driven process.
Contents
What's New in v0.3.7
The 0.3.7 release focuses on observability — giving developers and operations teams the visibility they need to understand exactly what their D365 F&O integrations are doing at every layer.
| Feature | Impact |
|---|---|
| Request Tracing | Correlate every HTTP call with Activity ID + Request ID |
| Server Timing | Surface D365 server-side processing time in responses |
| Entity Validation | Pre-flight checks before CRUD operations |
| Dependency Updates | MCP framework 1.21.1 → 1.27.0, uvicorn 0.38 → 0.44 |
Request Tracing Deep Dive
Modern distributed systems live and die by their ability to trace a single request through multiple layers. The new request tracing system brings that capability to every D365 F&O operation.
Activity ID & Request ID Tracking
Every HTTP call now carries two identifiers:
- Activity ID — maps to D365's own correlation ID, letting you cross-reference your client logs with the D365 server-side traces in Application Insights or the D365 activity log.
- Request ID — a client-generated identifier that stays with the request as it moves through client, CRUD, metadata, and label operations.
These IDs are included in response metadata, meaning you can programmatically extract them for downstream correlation — log aggregators, dashboards, alerting pipelines.
Enabling Request Tracing
Opt in with a single configuration flag:
from d365fo_client import FOClient, FOClientConfig
config = FOClientConfig(
base_url="https://your-d365-instance.operations.dynamics.com",
enable_request_tracing=True, # 👈 new in v0.3.7
)
client = FOClient(config)With tracing enabled, every operation — reads, creates, updates, deletes, metadata fetches, label lookups — will carry and propagate trace IDs throughout its lifecycle.
Trace IDs in Exception Messages
Before v0.3.7, a failed D365 operation would throw a generic error. Now, exception messages include the trace ID:
D365FOException: Entity 'CustTable' returned HTTP 400.
Activity-Id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
Request-Id: req_9f8e7d6c5b4a
→ Use these IDs to query D365 Activity Log or Application Insights.No more "which request caused that error?" moments. You have the exact correlation handle.
Trace Propagation Across All Operations
Tracing isn't limited to top-level CRUD calls. Trace IDs propagate through:
- Client layer — base HTTP operations
- CRUD tools — create, read, update, delete via MCP
- Metadata operations — entity discovery and schema fetches
- Label operations — D365 label translations
This full-stack propagation means you can reconstruct the complete call chain even for complex multi-step operations.
Server Timing & Performance Visibility
Alongside request tracing, v0.3.7 surfaces server timing headers from D365 F&O HTTP responses. D365 embeds Server-Timing metadata in its responses — processing time, database query duration, and other server-side metrics — and the client now exposes these through response metadata.
Why Server Timing Matters
When an operation is slow, you need to know where the time is going:
- Is it network latency? — Client → D365 round-trip time
- Is it D365 server processing? — Entity query, business logic execution
- Is it your integration layer? — Serialization, validation, protocol overhead
With server timing data in your hands, you can answer these questions without guesswork. You can build performance dashboards, set SLA thresholds, and detect degradation before your users do.
Accessing Timing Data
Server timing values flow through the same response metadata as trace IDs:
result = await client.crud.read_entity("SalesOrderHeaderV2", top=10)
# Trace & timing metadata
print(result.metadata.get("activity_id"))
print(result.metadata.get("request_id"))
print(result.metadata.get("server_timing")) # Server-side processing msPair this with your existing observability stack — whether that's Application Insights, Grafana, or a custom logging pipeline — and you have end-to-end timing visibility across your entire D365 integration surface.
Entity Validation Improvements
The CRUD tools mixin gained pre-flight entity validation — checking whether an entity is accessible before attempting an operation:
# Before v0.3.7: operation fails mid-execution with a cryptic error
# After v0.3.7: validation fires before execution, clear error up front
# Example output when entity is inaccessible:
# ValidationError: Entity 'MyCustomEntity' is not accessible on this environment.
# Ensure the entity is enabled and your credentials have sufficient permissions.Schema Consistency Validation
Key fields are now validated for schema consistency before operations execute. This catches mismatches between your code's assumptions and the actual D365 entity schema — a common source of subtle integration bugs, especially after D365 updates.
The validation layer also ships with an expanded BaseToolsMixin (+190 lines) that centralizes:
- Entity accessibility checks
- Error response formatting
- Schema validation utilities
How to Upgrade
# pip
pip install d365fo-client==0.3.7
# uv (recommended)
uv add d365fo-client==0.3.7
# MCP Server via uvx
uvx d365fo-mcp-server --version
# Docker
docker pull ghcr.io/mafzaal/d365fo-client:0.3.7
# or
docker pull ghcr.io/mafzaal/d365fo-client:latestEnable request tracing by adding enable_request_tracing=True to your FOClientConfig or setting the environment variable:
export D365FO_ENABLE_REQUEST_TRACING=trueNo other breaking changes in this release — the upgrade is a straight drop-in.
Full Release Notes Summary
v0.3.7 — 2026-04-18
✨ Added
- Comprehensive request tracing with Activity ID + Request ID propagation
enable_request_tracingconfiguration option- Trace IDs in exception messages and response metadata
- Server timing visibility via response metadata
- Pre-flight entity accessibility validation
- Schema consistency validation for key fields
- 190+ lines of enhanced
BaseToolsMixininfrastructure
🔧 Improved
- Error handling across all CRUD tools and integration tests
- Graceful connection error handling in test suite
- Service discovery specification documentation
- AI assistant integration documentation (1,058 lines → 53 lines of focused content)
📦 Dependencies
- MCP framework:
1.21.1→1.27.0 - uvicorn:
0.38.0→0.44.0 - aiohttp:
3.13.2→3.13.5 - rich:
14.2.0→15.0.0 - authlib:
1.6.5→1.6.9 - azure-identity:
1.25.1→1.25.3 - ruff, black, mypy, pytest — all updated to latest
Get in Touch
Need help integrating the new request tracing into your D365 F&O observability pipeline? Want to discuss custom integration solutions or enterprise AI consulting?
Connect with me:
- 📧 Email: [email protected]
- 🐦 Twitter/X: @TheDataGuyPro
- 💼 LinkedIn: Muhammad Afzaal
- 💻 GitHub: @mafzaal
- 🎥 YouTube: @TheDataGuyPro
- 🎧 Podcast: TheDataGuy Show
Whether you're looking for consulting services, training, or just want to discuss D365 F&O automation strategies, I'd love to hear from you!