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,371 @@
|
|
1
|
+
"""MCP-specific models and data structures."""
|
2
|
+
|
3
|
+
from dataclasses import dataclass
|
4
|
+
from datetime import datetime
|
5
|
+
from enum import Enum
|
6
|
+
from typing import Any, Dict, List, Optional, Union
|
7
|
+
|
8
|
+
# Resource Models
|
9
|
+
|
10
|
+
|
11
|
+
@dataclass
|
12
|
+
class EntityProperty:
|
13
|
+
name: str
|
14
|
+
type: str
|
15
|
+
is_key: bool
|
16
|
+
is_required: bool
|
17
|
+
max_length: Optional[int] = None
|
18
|
+
label: Optional[str] = None
|
19
|
+
description: Optional[str] = None
|
20
|
+
|
21
|
+
|
22
|
+
@dataclass
|
23
|
+
class EntityMetadata:
|
24
|
+
name: str
|
25
|
+
entity_set_name: str
|
26
|
+
keys: List[str]
|
27
|
+
properties: List[EntityProperty]
|
28
|
+
is_read_only: bool
|
29
|
+
label_text: Optional[str] = None
|
30
|
+
|
31
|
+
|
32
|
+
@dataclass
|
33
|
+
class EntityResourceContent:
|
34
|
+
metadata: Optional[EntityMetadata]
|
35
|
+
sample_data: Optional[List[Dict[str, Any]]] = None
|
36
|
+
record_count: Optional[int] = None
|
37
|
+
last_updated: Optional[str] = None
|
38
|
+
|
39
|
+
|
40
|
+
class MetadataType(Enum):
|
41
|
+
ENTITIES = "entities"
|
42
|
+
ACTIONS = "actions"
|
43
|
+
ENUMERATIONS = "enumerations"
|
44
|
+
LABELS = "labels"
|
45
|
+
|
46
|
+
|
47
|
+
@dataclass
|
48
|
+
class MetadataStatistics:
|
49
|
+
categories: Dict[str, int]
|
50
|
+
capabilities: Dict[str, int]
|
51
|
+
|
52
|
+
|
53
|
+
@dataclass
|
54
|
+
class MetadataResourceContent:
|
55
|
+
type: MetadataType
|
56
|
+
count: int
|
57
|
+
last_updated: str
|
58
|
+
items: List[Dict[str, Any]]
|
59
|
+
statistics: Optional[MetadataStatistics] = None
|
60
|
+
|
61
|
+
|
62
|
+
@dataclass
|
63
|
+
class VersionInfo:
|
64
|
+
application: str
|
65
|
+
platform: str
|
66
|
+
build: str
|
67
|
+
|
68
|
+
|
69
|
+
@dataclass
|
70
|
+
class ConnectivityStatus:
|
71
|
+
data_endpoint: bool
|
72
|
+
metadata_endpoint: bool
|
73
|
+
last_tested: str
|
74
|
+
|
75
|
+
|
76
|
+
@dataclass
|
77
|
+
class CacheInfo:
|
78
|
+
size: int
|
79
|
+
last_updated: str
|
80
|
+
hit_rate: float
|
81
|
+
|
82
|
+
|
83
|
+
@dataclass
|
84
|
+
class CacheStatus:
|
85
|
+
metadata: CacheInfo
|
86
|
+
labels: CacheInfo
|
87
|
+
|
88
|
+
|
89
|
+
@dataclass
|
90
|
+
class EnvironmentResourceContent:
|
91
|
+
base_url: str
|
92
|
+
version: VersionInfo
|
93
|
+
connectivity: ConnectivityStatus
|
94
|
+
cache: CacheStatus
|
95
|
+
|
96
|
+
|
97
|
+
@dataclass
|
98
|
+
class QueryParameter:
|
99
|
+
name: str
|
100
|
+
type: str
|
101
|
+
required: bool
|
102
|
+
description: str
|
103
|
+
default_value: Optional[Any] = None
|
104
|
+
|
105
|
+
|
106
|
+
@dataclass
|
107
|
+
class QueryResourceContent:
|
108
|
+
entity_name: str
|
109
|
+
select: Optional[List[str]] = None
|
110
|
+
filter: Optional[str] = None
|
111
|
+
expand: Optional[List[str]] = None
|
112
|
+
order_by: Optional[List[str]] = None
|
113
|
+
top: Optional[int] = None
|
114
|
+
skip: Optional[int] = None
|
115
|
+
template: bool = False
|
116
|
+
parameters: Optional[List[QueryParameter]] = None
|
117
|
+
|
118
|
+
|
119
|
+
# Tool Input/Output Models
|
120
|
+
|
121
|
+
|
122
|
+
@dataclass
|
123
|
+
class TestConnectionInput:
|
124
|
+
base_url: Optional[str] = None
|
125
|
+
timeout: Optional[int] = None
|
126
|
+
|
127
|
+
|
128
|
+
@dataclass
|
129
|
+
class EndpointStatus:
|
130
|
+
data: bool
|
131
|
+
metadata: bool
|
132
|
+
|
133
|
+
|
134
|
+
@dataclass
|
135
|
+
class TestConnectionOutput:
|
136
|
+
success: bool
|
137
|
+
endpoints: EndpointStatus
|
138
|
+
response_time: float
|
139
|
+
error: Optional[str] = None
|
140
|
+
|
141
|
+
|
142
|
+
@dataclass
|
143
|
+
class EnvironmentInfoOutput:
|
144
|
+
base_url: str
|
145
|
+
versions: VersionInfo
|
146
|
+
connectivity: bool
|
147
|
+
cache_status: CacheStatus
|
148
|
+
statistics: Optional[Dict[str, int]] = None
|
149
|
+
|
150
|
+
|
151
|
+
@dataclass
|
152
|
+
class SyncMetadataInput:
|
153
|
+
force_refresh: bool = False
|
154
|
+
include_labels: bool = True
|
155
|
+
include_actions: bool = True
|
156
|
+
|
157
|
+
|
158
|
+
@dataclass
|
159
|
+
class SyncStatistics:
|
160
|
+
entities_downloaded: int
|
161
|
+
actions_downloaded: int
|
162
|
+
labels_downloaded: int
|
163
|
+
|
164
|
+
|
165
|
+
@dataclass
|
166
|
+
class SyncMetadataOutput:
|
167
|
+
success: bool
|
168
|
+
sync_time: float
|
169
|
+
statistics: SyncStatistics
|
170
|
+
cache_location: str
|
171
|
+
|
172
|
+
|
173
|
+
@dataclass
|
174
|
+
class SearchEntitiesInput:
|
175
|
+
pattern: str
|
176
|
+
entity_category: Optional[str] = None
|
177
|
+
data_service_enabled: Optional[bool] = None
|
178
|
+
data_management_enabled: Optional[bool] = None
|
179
|
+
is_read_only: Optional[bool] = None
|
180
|
+
limit: int = 100
|
181
|
+
|
182
|
+
|
183
|
+
@dataclass
|
184
|
+
class SearchEntitiesOutput:
|
185
|
+
entities: List[Dict[str, Any]]
|
186
|
+
total_count: int
|
187
|
+
search_time: float
|
188
|
+
|
189
|
+
|
190
|
+
@dataclass
|
191
|
+
class QueryEntitiesInput:
|
192
|
+
entity_name: str
|
193
|
+
select: Optional[List[str]] = None
|
194
|
+
filter: Optional[str] = None
|
195
|
+
expand: Optional[List[str]] = None
|
196
|
+
order_by: Optional[List[str]] = None
|
197
|
+
top: Optional[int] = None
|
198
|
+
skip: Optional[int] = None
|
199
|
+
count: bool = False
|
200
|
+
search: Optional[str] = None
|
201
|
+
|
202
|
+
|
203
|
+
@dataclass
|
204
|
+
class QueryEntitiesOutput:
|
205
|
+
data: List[Dict[str, Any]]
|
206
|
+
count: Optional[int] = None
|
207
|
+
next_link: Optional[str] = None
|
208
|
+
query_time: float = 0.0
|
209
|
+
total_records: Optional[int] = None
|
210
|
+
|
211
|
+
|
212
|
+
@dataclass
|
213
|
+
class GetEntityRecordInput:
|
214
|
+
entity_name: str
|
215
|
+
key: Union[str, Dict[str, Any]]
|
216
|
+
select: Optional[List[str]] = None
|
217
|
+
expand: Optional[List[str]] = None
|
218
|
+
|
219
|
+
|
220
|
+
@dataclass
|
221
|
+
class GetEntityRecordOutput:
|
222
|
+
record: Optional[Dict[str, Any]]
|
223
|
+
found: bool
|
224
|
+
retrieval_time: float
|
225
|
+
|
226
|
+
|
227
|
+
@dataclass
|
228
|
+
class CreateEntityRecordInput:
|
229
|
+
entity_name: str
|
230
|
+
data: Dict[str, Any]
|
231
|
+
return_record: bool = False
|
232
|
+
|
233
|
+
|
234
|
+
@dataclass
|
235
|
+
class CreateEntityRecordOutput:
|
236
|
+
success: bool
|
237
|
+
record_id: Optional[str] = None
|
238
|
+
created_record: Optional[Dict[str, Any]] = None
|
239
|
+
validation_errors: Optional[List[str]] = None
|
240
|
+
|
241
|
+
|
242
|
+
@dataclass
|
243
|
+
class UpdateEntityRecordInput:
|
244
|
+
entity_name: str
|
245
|
+
key: Union[str, Dict[str, Any]]
|
246
|
+
data: Dict[str, Any]
|
247
|
+
return_record: bool = False
|
248
|
+
if_match: Optional[str] = None
|
249
|
+
|
250
|
+
|
251
|
+
@dataclass
|
252
|
+
class UpdateEntityRecordOutput:
|
253
|
+
success: bool
|
254
|
+
updated_record: Optional[Dict[str, Any]] = None
|
255
|
+
validation_errors: Optional[List[str]] = None
|
256
|
+
conflict_detected: bool = False
|
257
|
+
|
258
|
+
|
259
|
+
@dataclass
|
260
|
+
class DeleteEntityRecordInput:
|
261
|
+
entity_name: str
|
262
|
+
key: Union[str, Dict[str, Any]]
|
263
|
+
if_match: Optional[str] = None
|
264
|
+
|
265
|
+
|
266
|
+
@dataclass
|
267
|
+
class DeleteEntityRecordOutput:
|
268
|
+
success: bool
|
269
|
+
conflict_detected: bool = False
|
270
|
+
error: Optional[str] = None
|
271
|
+
|
272
|
+
|
273
|
+
@dataclass
|
274
|
+
class GetLabelInput:
|
275
|
+
label_id: str
|
276
|
+
language: str = "en-US"
|
277
|
+
fallback_to_english: bool = True
|
278
|
+
|
279
|
+
|
280
|
+
@dataclass
|
281
|
+
class GetLabelOutput:
|
282
|
+
label_id: str
|
283
|
+
text: str
|
284
|
+
language: str
|
285
|
+
found: bool
|
286
|
+
|
287
|
+
|
288
|
+
@dataclass
|
289
|
+
class GetLabelsBatchInput:
|
290
|
+
label_ids: List[str]
|
291
|
+
language: str = "en-US"
|
292
|
+
fallback_to_english: bool = True
|
293
|
+
|
294
|
+
|
295
|
+
@dataclass
|
296
|
+
class GetLabelsBatchOutput:
|
297
|
+
labels: Dict[str, str]
|
298
|
+
missing_labels: List[str]
|
299
|
+
retrieval_time: float
|
300
|
+
|
301
|
+
|
302
|
+
# Error Models
|
303
|
+
|
304
|
+
|
305
|
+
@dataclass
|
306
|
+
class D365FOErrorDetails:
|
307
|
+
http_status: int
|
308
|
+
error_code: str
|
309
|
+
error_message: str
|
310
|
+
correlation_id: Optional[str] = None
|
311
|
+
|
312
|
+
|
313
|
+
@dataclass
|
314
|
+
class MCPErrorDetails:
|
315
|
+
d365fo_error: Optional[D365FOErrorDetails] = None
|
316
|
+
validation_errors: Optional[List[str]] = None
|
317
|
+
context: Optional[Dict[str, Any]] = None
|
318
|
+
|
319
|
+
|
320
|
+
@dataclass
|
321
|
+
class MCPError:
|
322
|
+
code: str
|
323
|
+
message: str
|
324
|
+
timestamp: str
|
325
|
+
details: Optional[MCPErrorDetails] = None
|
326
|
+
tool: Optional[str] = None
|
327
|
+
retryable: bool = False
|
328
|
+
|
329
|
+
|
330
|
+
# Configuration Models
|
331
|
+
|
332
|
+
|
333
|
+
@dataclass
|
334
|
+
class PerformanceConfig:
|
335
|
+
max_concurrent_requests: int = 10
|
336
|
+
connection_pool_size: int = 5
|
337
|
+
request_timeout: int = 30
|
338
|
+
batch_size: int = 100
|
339
|
+
|
340
|
+
|
341
|
+
@dataclass
|
342
|
+
class CacheConfig:
|
343
|
+
metadata_cache_dir: str
|
344
|
+
label_cache_expiry_minutes: int = 120
|
345
|
+
use_label_cache: bool = True
|
346
|
+
cache_size_limit_mb: int = 100
|
347
|
+
|
348
|
+
|
349
|
+
@dataclass
|
350
|
+
class SecurityConfig:
|
351
|
+
encrypt_cached_tokens: bool = True
|
352
|
+
token_expiry_buffer_minutes: int = 5
|
353
|
+
max_retry_attempts: int = 3
|
354
|
+
|
355
|
+
|
356
|
+
@dataclass
|
357
|
+
class MCPServerConfig:
|
358
|
+
name: str = "d365fo-mcp-server"
|
359
|
+
version: str = "1.0.0"
|
360
|
+
description: str = "MCP Server for Microsoft Dynamics 365 Finance & Operations"
|
361
|
+
performance: PerformanceConfig = None
|
362
|
+
cache: CacheConfig = None
|
363
|
+
security: SecurityConfig = None
|
364
|
+
|
365
|
+
def __post_init__(self):
|
366
|
+
if self.performance is None:
|
367
|
+
self.performance = PerformanceConfig()
|
368
|
+
if self.cache is None:
|
369
|
+
self.cache = CacheConfig(metadata_cache_dir="~/.d365fo-mcp/cache")
|
370
|
+
if self.security is None:
|
371
|
+
self.security = SecurityConfig()
|
@@ -0,0 +1,43 @@
|
|
1
|
+
"""Prompts package for MCP server."""
|
2
|
+
|
3
|
+
from .action_execution import (
|
4
|
+
ACTION_EXECUTION_PROMPT,
|
5
|
+
ActionBindingKind,
|
6
|
+
ActionExecutionPrompt,
|
7
|
+
ActionExecutionPromptArgs,
|
8
|
+
ActionExecutionType,
|
9
|
+
)
|
10
|
+
from .sequence_analysis import (
|
11
|
+
SEQUENCE_ANALYSIS_PROMPT,
|
12
|
+
SequenceAnalysisPrompt,
|
13
|
+
SequenceAnalysisPromptArgs,
|
14
|
+
SequenceAnalysisType,
|
15
|
+
SequenceScope,
|
16
|
+
)
|
17
|
+
|
18
|
+
# Available prompts for MCP server
|
19
|
+
AVAILABLE_PROMPTS = {
|
20
|
+
"d365fo_sequence_analysis": SEQUENCE_ANALYSIS_PROMPT,
|
21
|
+
"d365fo_action_execution": ACTION_EXECUTION_PROMPT,
|
22
|
+
}
|
23
|
+
|
24
|
+
# Future: Additional prompt handlers will be implemented here
|
25
|
+
# Following the specification patterns for:
|
26
|
+
# - Entity analysis prompts
|
27
|
+
# - Query builder prompts
|
28
|
+
# - Integration planning prompts
|
29
|
+
# - Troubleshooting prompts
|
30
|
+
|
31
|
+
__all__ = [
|
32
|
+
"SEQUENCE_ANALYSIS_PROMPT",
|
33
|
+
"SequenceAnalysisPrompt",
|
34
|
+
"SequenceAnalysisPromptArgs",
|
35
|
+
"SequenceAnalysisType",
|
36
|
+
"SequenceScope",
|
37
|
+
"ACTION_EXECUTION_PROMPT",
|
38
|
+
"ActionExecutionPrompt",
|
39
|
+
"ActionExecutionPromptArgs",
|
40
|
+
"ActionExecutionType",
|
41
|
+
"ActionBindingKind",
|
42
|
+
"AVAILABLE_PROMPTS",
|
43
|
+
]
|