d365fo-client 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- d365fo_client/__init__.py +305 -0
- d365fo_client/auth.py +93 -0
- d365fo_client/cli.py +700 -0
- d365fo_client/client.py +1454 -0
- d365fo_client/config.py +304 -0
- d365fo_client/crud.py +200 -0
- d365fo_client/exceptions.py +49 -0
- d365fo_client/labels.py +528 -0
- d365fo_client/main.py +502 -0
- d365fo_client/mcp/__init__.py +16 -0
- d365fo_client/mcp/client_manager.py +276 -0
- d365fo_client/mcp/main.py +98 -0
- d365fo_client/mcp/models.py +371 -0
- d365fo_client/mcp/prompts/__init__.py +43 -0
- d365fo_client/mcp/prompts/action_execution.py +480 -0
- d365fo_client/mcp/prompts/sequence_analysis.py +349 -0
- d365fo_client/mcp/resources/__init__.py +15 -0
- d365fo_client/mcp/resources/database_handler.py +555 -0
- d365fo_client/mcp/resources/entity_handler.py +176 -0
- d365fo_client/mcp/resources/environment_handler.py +132 -0
- d365fo_client/mcp/resources/metadata_handler.py +283 -0
- d365fo_client/mcp/resources/query_handler.py +135 -0
- d365fo_client/mcp/server.py +432 -0
- d365fo_client/mcp/tools/__init__.py +17 -0
- d365fo_client/mcp/tools/connection_tools.py +175 -0
- d365fo_client/mcp/tools/crud_tools.py +579 -0
- d365fo_client/mcp/tools/database_tools.py +813 -0
- d365fo_client/mcp/tools/label_tools.py +189 -0
- d365fo_client/mcp/tools/metadata_tools.py +766 -0
- d365fo_client/mcp/tools/profile_tools.py +706 -0
- d365fo_client/metadata_api.py +793 -0
- d365fo_client/metadata_v2/__init__.py +59 -0
- d365fo_client/metadata_v2/cache_v2.py +1372 -0
- d365fo_client/metadata_v2/database_v2.py +585 -0
- d365fo_client/metadata_v2/global_version_manager.py +573 -0
- d365fo_client/metadata_v2/search_engine_v2.py +423 -0
- d365fo_client/metadata_v2/sync_manager_v2.py +819 -0
- d365fo_client/metadata_v2/version_detector.py +439 -0
- d365fo_client/models.py +862 -0
- d365fo_client/output.py +181 -0
- d365fo_client/profile_manager.py +342 -0
- d365fo_client/profiles.py +178 -0
- d365fo_client/query.py +162 -0
- d365fo_client/session.py +60 -0
- d365fo_client/utils.py +196 -0
- d365fo_client-0.1.0.dist-info/METADATA +1084 -0
- d365fo_client-0.1.0.dist-info/RECORD +51 -0
- d365fo_client-0.1.0.dist-info/WHEEL +5 -0
- d365fo_client-0.1.0.dist-info/entry_points.txt +3 -0
- d365fo_client-0.1.0.dist-info/licenses/LICENSE +21 -0
- d365fo_client-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,349 @@
|
|
1
|
+
"""
|
2
|
+
D365 Finance & Operations Sequence Analysis Prompt for MCP.
|
3
|
+
|
4
|
+
This module provides a comprehensive prompt for analyzing D365FO number sequences
|
5
|
+
with validated entity schemas and query limitations.
|
6
|
+
"""
|
7
|
+
|
8
|
+
from enum import Enum
|
9
|
+
from typing import Any, Dict, List, Optional
|
10
|
+
|
11
|
+
from pydantic import BaseModel, Field
|
12
|
+
|
13
|
+
|
14
|
+
class SequenceAnalysisType(str, Enum):
|
15
|
+
"""Types of sequence analysis."""
|
16
|
+
|
17
|
+
COMPREHENSIVE = "comprehensive"
|
18
|
+
BASIC = "basic"
|
19
|
+
SPECIFIC_SEQUENCES = "specific_sequences"
|
20
|
+
PERFORMANCE_FOCUS = "performance_focus"
|
21
|
+
|
22
|
+
|
23
|
+
class SequenceScope(str, Enum):
|
24
|
+
"""Sequence scope types."""
|
25
|
+
|
26
|
+
DATA_AREA = "DataArea"
|
27
|
+
DATA_AREA_FISCAL = "DataAreaFiscalCalender"
|
28
|
+
LEGAL_ENTITY = "LegalEntity"
|
29
|
+
OPERATING_UNIT = "OperatingUnit"
|
30
|
+
|
31
|
+
|
32
|
+
class SequenceAnalysisPromptArgs(BaseModel):
|
33
|
+
"""Arguments for sequence analysis prompt."""
|
34
|
+
|
35
|
+
analysis_scope: SequenceAnalysisType = Field(
|
36
|
+
default=SequenceAnalysisType.COMPREHENSIVE,
|
37
|
+
description="Scope of analysis: comprehensive, basic, specific_sequences, performance_focus",
|
38
|
+
)
|
39
|
+
company_filter: Optional[str] = Field(
|
40
|
+
default=None,
|
41
|
+
description="Filter analysis to specific company code (e.g., 'USMF')",
|
42
|
+
)
|
43
|
+
sequence_codes: Optional[List[str]] = Field(
|
44
|
+
default=None,
|
45
|
+
description="Specific sequence codes to analyze (e.g., ['Addr_1', 'Cust_1'])",
|
46
|
+
)
|
47
|
+
focus_areas: List[str] = Field(
|
48
|
+
default=["configuration", "performance", "security", "maintenance"],
|
49
|
+
description="Areas to focus analysis on",
|
50
|
+
)
|
51
|
+
|
52
|
+
|
53
|
+
# Validated entity field mappings from live D365FO environment
|
54
|
+
SEQUENCE_ENTITY_FIELDS = {
|
55
|
+
"SequenceV2Tables": [
|
56
|
+
"NumberSequenceCode",
|
57
|
+
"ScopeType",
|
58
|
+
"ScopeValue",
|
59
|
+
"Name",
|
60
|
+
"Next", # Changed from NextRec
|
61
|
+
"Format",
|
62
|
+
"Preallocation",
|
63
|
+
"Manual",
|
64
|
+
"ToALowerNumber", # Additional field found
|
65
|
+
"Cyclical",
|
66
|
+
"Continuous",
|
67
|
+
"Stopped",
|
68
|
+
"InUse",
|
69
|
+
],
|
70
|
+
"NumberSequencesV2References": [
|
71
|
+
"DataTypeName",
|
72
|
+
"NumberSequenceCode",
|
73
|
+
"ReuseNumbers",
|
74
|
+
"ScopeType",
|
75
|
+
"ScopeValue",
|
76
|
+
],
|
77
|
+
}
|
78
|
+
|
79
|
+
|
80
|
+
class SequenceAnalysisPrompt:
|
81
|
+
"""Sequence number analysis prompt handler."""
|
82
|
+
|
83
|
+
@staticmethod
|
84
|
+
def get_prompt_template() -> str:
|
85
|
+
"""Get the prompt template for sequence analysis."""
|
86
|
+
return """
|
87
|
+
# D365 Finance & Operations Number Sequence Analysis
|
88
|
+
|
89
|
+
You are an expert D365 Finance & Operations consultant specializing in number sequence analysis. You have access to D365FO MCP tools to analyze number sequences directly from the system.
|
90
|
+
|
91
|
+
## Your Mission
|
92
|
+
Analyze D365 Finance & Operations number sequences to identify configuration issues, optimization opportunities, and provide actionable recommendations. Use the MCP tools to gather real-time data from the system.
|
93
|
+
|
94
|
+
## Available MCP Tools
|
95
|
+
|
96
|
+
**Entity Query Tools:**
|
97
|
+
- `d365fo_query_entities` - Query D365FO entities (limited OData support)
|
98
|
+
- `d365fo_get_entity_by_key` - Get specific entity record by key
|
99
|
+
- `d365fo_search_entities` - Search for entities by name pattern
|
100
|
+
- `d365fo_get_entity_schema` - Get entity metadata and schema information
|
101
|
+
|
102
|
+
**Version & System Tools:**
|
103
|
+
- `d365fo_get_environment_info` - Get D365FO application version and environment info
|
104
|
+
- `d365fo_test_connection` - Test connection to D365FO environment
|
105
|
+
|
106
|
+
## Key Entities for Sequence Analysis
|
107
|
+
|
108
|
+
### Primary Entities (Validated and Working)
|
109
|
+
- **SequenceV2Tables** - Main number sequence definitions ✅
|
110
|
+
- Key fields: NumberSequenceCode, Name, Manual, Stopped, InUse, Cyclical, Continuous, ScopeType, ScopeValue, Next, Format, Preallocation
|
111
|
+
- **NumberSequencesV2References** - Number sequence references and assignments ✅
|
112
|
+
- Key fields: NumberSequenceCode, DataTypeName, ReuseNumbers, ScopeType, ScopeValue
|
113
|
+
|
114
|
+
### Field Values (Validated from Live System)
|
115
|
+
All boolean/enum fields use string values:
|
116
|
+
- **Manual**: 'Yes', 'No'
|
117
|
+
- **Stopped**: 'No' (mostly 'No' in system)
|
118
|
+
- **InUse**: 'Yes', 'No'
|
119
|
+
- **Cyclical**: 'No' (mostly 'No' in system)
|
120
|
+
- **Continuous**: 'Yes', 'No'
|
121
|
+
- **ScopeType**: 'DataArea', 'DataAreaFiscalCalender', 'LegalEntity', 'OperatingUnit'
|
122
|
+
|
123
|
+
### Query Limitations (Important!)
|
124
|
+
This D365FO environment has limited OData capabilities:
|
125
|
+
- ✅ **Works**: Basic entity retrieval, simple key-based filters
|
126
|
+
- ❌ **Fails**: Field filtering on Manual/Stopped/InUse, $select, $orderby, complex filters
|
127
|
+
|
128
|
+
**Working Filter Examples:**
|
129
|
+
```
|
130
|
+
NumberSequenceCode eq 'Addr_1' ✅ Works
|
131
|
+
```
|
132
|
+
|
133
|
+
**Non-Working Filters (Return 400 errors):**
|
134
|
+
```
|
135
|
+
Manual eq 'Yes' ❌ Fails
|
136
|
+
InUse eq 'Yes' ❌ Fails
|
137
|
+
ScopeType eq 'DataArea' ❌ Fails
|
138
|
+
Manual eq Microsoft.Dynamics.DataEntities.NoYes'Yes' ❌ Fails
|
139
|
+
```
|
140
|
+
|
141
|
+
## Analysis Framework
|
142
|
+
|
143
|
+
### 1. System Overview
|
144
|
+
Start every analysis by gathering system information:
|
145
|
+
```
|
146
|
+
Use d365fo_get_environment_info to identify D365FO version and environment
|
147
|
+
Use d365fo_query_entities with entity_name="SequenceV2Tables" (NO FILTERS) to get all data
|
148
|
+
```
|
149
|
+
|
150
|
+
### 2. Data Collection Strategy
|
151
|
+
Due to query limitations, collect all data first then analyze in memory:
|
152
|
+
```
|
153
|
+
1. Get ALL SequenceV2Tables data (no filters)
|
154
|
+
2. Get ALL NumberSequencesV2References data (no filters)
|
155
|
+
3. Filter and analyze the results programmatically
|
156
|
+
```
|
157
|
+
|
158
|
+
### 3. Manual Analysis Approach
|
159
|
+
Since field filtering doesn't work, analyze data manually:
|
160
|
+
- Load all sequence records into memory
|
161
|
+
- Filter records by checking field values programmatically
|
162
|
+
- Count sequences by categories (Manual='Yes', InUse='Yes', etc.)
|
163
|
+
- Identify patterns and issues through data analysis
|
164
|
+
|
165
|
+
### 4. Configuration Analysis
|
166
|
+
For each sequence category, analyze:
|
167
|
+
- **Scope Distribution**: Count by ScopeType values
|
168
|
+
- **Usage Patterns**: Manual vs automatic sequences
|
169
|
+
- **Status Analysis**: Active, stopped, unused sequences
|
170
|
+
- **Format Analysis**: Number format patterns
|
171
|
+
- **Performance Considerations**: Preallocation settings
|
172
|
+
|
173
|
+
### 5. Reference Analysis
|
174
|
+
Understand sequence usage:
|
175
|
+
```
|
176
|
+
Use d365fo_query_entities with entity_name="NumberSequencesV2References" (no filters)
|
177
|
+
Cross-reference NumberSequenceCode with sequence definitions
|
178
|
+
Analyze DataTypeName to understand business context
|
179
|
+
```
|
180
|
+
|
181
|
+
## Step-by-Step Analysis Process
|
182
|
+
|
183
|
+
### Step 1: Environment Assessment
|
184
|
+
```
|
185
|
+
1. Use d365fo_get_environment_info to identify environment
|
186
|
+
2. Use d365fo_query_entities(entity_name="SequenceV2Tables") - get ALL records (10,000+ expected)
|
187
|
+
3. Count and categorize sequences programmatically:
|
188
|
+
- Total sequences
|
189
|
+
- Manual sequences (Manual='Yes')
|
190
|
+
- Active sequences (InUse='Yes')
|
191
|
+
- Stopped sequences (Stopped='Yes')
|
192
|
+
- Scope distribution
|
193
|
+
```
|
194
|
+
|
195
|
+
### Step 2: Active Sequence Analysis
|
196
|
+
From the collected data, programmatically filter for:
|
197
|
+
```
|
198
|
+
1. Active sequences: InUse='Yes'
|
199
|
+
2. Manual sequences: Manual='Yes' AND InUse='Yes'
|
200
|
+
3. Problem sequences: Stopped='Yes' AND InUse='Yes'
|
201
|
+
4. Scope analysis: Group by ScopeType values
|
202
|
+
```
|
203
|
+
|
204
|
+
### Step 3: Reference Analysis
|
205
|
+
```
|
206
|
+
1. Use d365fo_query_entities(entity_name="NumberSequencesV2References") - get ALL references
|
207
|
+
2. Cross-reference with sequence definitions
|
208
|
+
3. Identify unused sequences (in SequenceV2Tables but not in References)
|
209
|
+
4. Analyze DataTypeName patterns for business context
|
210
|
+
```
|
211
|
+
|
212
|
+
### Step 4: Configuration Deep Dive
|
213
|
+
For specific sequences of interest:
|
214
|
+
```
|
215
|
+
1. Use d365fo_get_entity_by_key to get detailed sequence information
|
216
|
+
2. Analyze Format patterns for readability
|
217
|
+
3. Check Preallocation settings for performance
|
218
|
+
4. Review ScopeValue configurations
|
219
|
+
```
|
220
|
+
|
221
|
+
### Step 5: Recommendations
|
222
|
+
Provide specific recommendations based on analysis:
|
223
|
+
- Manual to automatic conversion opportunities
|
224
|
+
- Format optimization suggestions
|
225
|
+
- Scope configuration improvements
|
226
|
+
- Performance tuning recommendations
|
227
|
+
- Risk mitigation strategies
|
228
|
+
|
229
|
+
## Data Analysis Examples
|
230
|
+
|
231
|
+
### Collect All Sequence Data
|
232
|
+
```
|
233
|
+
# Get all sequences (no filtering possible)
|
234
|
+
all_sequences = d365fo_query_entities(entity_name="SequenceV2Tables")
|
235
|
+
|
236
|
+
# Programmatically analyze
|
237
|
+
manual_sequences = [s for s in all_sequences['value'] if s.get('Manual') == 'Yes']
|
238
|
+
active_sequences = [s for s in all_sequences['value'] if s.get('InUse') == 'Yes']
|
239
|
+
stopped_sequences = [s for s in all_sequences['value'] if s.get('Stopped') == 'Yes']
|
240
|
+
```
|
241
|
+
|
242
|
+
### Scope Analysis
|
243
|
+
```
|
244
|
+
# Count by scope type
|
245
|
+
scope_counts = {}
|
246
|
+
for seq in all_sequences['value']:
|
247
|
+
scope = seq.get('ScopeType', 'Unknown')
|
248
|
+
scope_counts[scope] = scope_counts.get(scope, 0) + 1
|
249
|
+
```
|
250
|
+
|
251
|
+
### Find Problematic Sequences
|
252
|
+
```
|
253
|
+
# Manual sequences that should be automatic
|
254
|
+
manual_active = [s for s in all_sequences['value']
|
255
|
+
if s.get('Manual') == 'Yes' and s.get('InUse') == 'Yes']
|
256
|
+
|
257
|
+
# Stopped sequences still marked as in use
|
258
|
+
stopped_in_use = [s for s in all_sequences['value']
|
259
|
+
if s.get('Stopped') == 'Yes' and s.get('InUse') == 'Yes']
|
260
|
+
```
|
261
|
+
|
262
|
+
## Output Format
|
263
|
+
|
264
|
+
Structure your analysis as:
|
265
|
+
|
266
|
+
1. **Executive Summary** - Key findings and critical issues
|
267
|
+
2. **Environment Overview** - Version, total sequences, basic statistics
|
268
|
+
3. **Sequence Categories** - Breakdown by Manual/Auto, Active/Stopped, Scope
|
269
|
+
4. **Configuration Analysis** - Detailed findings from data analysis
|
270
|
+
5. **Reference Analysis** - Usage patterns and orphaned sequences
|
271
|
+
6. **Recommendations** - Prioritized action items with implementation guidance
|
272
|
+
7. **Risk Assessment** - Potential impacts of identified issues
|
273
|
+
|
274
|
+
## Important Constraints
|
275
|
+
|
276
|
+
- **No Field Filtering**: Cannot filter by Manual, InUse, Stopped, or other fields
|
277
|
+
- **No $select Operations**: Must retrieve full records
|
278
|
+
- **No $orderby**: Data comes in system order
|
279
|
+
- **Large Dataset**: Expect 10,000+ sequence records
|
280
|
+
- **Manual Analysis Required**: Filter and analyze data programmatically after retrieval
|
281
|
+
|
282
|
+
## Best Practices
|
283
|
+
|
284
|
+
1. **Collect First, Filter Later**: Get all data with simple d365fo_query_entities calls
|
285
|
+
2. **Programmatic Analysis**: Use code logic to filter and categorize
|
286
|
+
3. **Key-Based Lookups**: Use d365fo_get_entity_by_key for specific sequence details
|
287
|
+
4. **Reference Cross-Checking**: Compare sequences with their references
|
288
|
+
5. **Pattern Recognition**: Look for naming patterns, scope patterns, format patterns
|
289
|
+
|
290
|
+
Begin your analysis by using d365fo_get_environment_info and d365fo_query_entities(entity_name="SequenceV2Tables") to gather the foundation data, then build your insights through programmatic analysis of the retrieved records.
|
291
|
+
"""
|
292
|
+
|
293
|
+
@staticmethod
|
294
|
+
def get_data_retrieval_queries() -> dict:
|
295
|
+
"""Get standard data retrieval queries for sequence analysis."""
|
296
|
+
return {
|
297
|
+
"all_sequences": {
|
298
|
+
"entity_name": "SequenceV2Tables",
|
299
|
+
"description": "Get all number sequences (no filtering due to OData limitations)",
|
300
|
+
},
|
301
|
+
"sequence_references": {
|
302
|
+
"entity_name": "NumberSequencesV2References",
|
303
|
+
"description": "Get all sequence references (no filtering due to OData limitations)",
|
304
|
+
},
|
305
|
+
"specific_sequence": {
|
306
|
+
"entity_name": "SequenceV2Tables",
|
307
|
+
"key_field": "NumberSequenceCode",
|
308
|
+
"description": "Get specific sequence by code using get_entity_by_key",
|
309
|
+
},
|
310
|
+
}
|
311
|
+
|
312
|
+
@staticmethod
|
313
|
+
def get_analysis_metadata() -> dict:
|
314
|
+
"""Get metadata for sequence analysis."""
|
315
|
+
return {
|
316
|
+
"version": "2.0",
|
317
|
+
"validated_entities": ["SequenceV2Tables", "NumberSequencesV2References"],
|
318
|
+
"known_limitations": [
|
319
|
+
"No field filtering on enum/boolean fields",
|
320
|
+
"No $select operations",
|
321
|
+
"No $orderby operations",
|
322
|
+
"Manual data analysis required",
|
323
|
+
],
|
324
|
+
"field_values": {
|
325
|
+
"Manual": ["Yes", "No"],
|
326
|
+
"Stopped": ["Yes", "No"],
|
327
|
+
"InUse": ["Yes", "No"],
|
328
|
+
"Cyclical": ["Yes", "No"],
|
329
|
+
"Continuous": ["Yes", "No"],
|
330
|
+
"ScopeType": [
|
331
|
+
"DataArea",
|
332
|
+
"DataAreaFiscalCalender",
|
333
|
+
"LegalEntity",
|
334
|
+
"OperatingUnit",
|
335
|
+
],
|
336
|
+
},
|
337
|
+
"expected_record_count": "10000+",
|
338
|
+
"analysis_approach": "collect_all_then_filter",
|
339
|
+
}
|
340
|
+
|
341
|
+
|
342
|
+
# Export the complete prompt configuration
|
343
|
+
SEQUENCE_ANALYSIS_PROMPT = {
|
344
|
+
"name": "sequence_analysis",
|
345
|
+
"description": "Comprehensive D365 Finance & Operations number sequence analysis with validated entity schemas and query limitations",
|
346
|
+
"template": SequenceAnalysisPrompt.get_prompt_template(),
|
347
|
+
"data_queries": SequenceAnalysisPrompt.get_data_retrieval_queries(),
|
348
|
+
"metadata": SequenceAnalysisPrompt.get_analysis_metadata(),
|
349
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
"""Resource handlers package."""
|
2
|
+
|
3
|
+
from .database_handler import DatabaseResourceHandler
|
4
|
+
from .entity_handler import EntityResourceHandler
|
5
|
+
from .environment_handler import EnvironmentResourceHandler
|
6
|
+
from .metadata_handler import MetadataResourceHandler
|
7
|
+
from .query_handler import QueryResourceHandler
|
8
|
+
|
9
|
+
__all__ = [
|
10
|
+
"EntityResourceHandler",
|
11
|
+
"MetadataResourceHandler",
|
12
|
+
"EnvironmentResourceHandler",
|
13
|
+
"QueryResourceHandler",
|
14
|
+
"DatabaseResourceHandler",
|
15
|
+
]
|