pyDMNrules-enhanced 1.5.0__tar.gz

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.
@@ -0,0 +1,24 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2020 Russell McDonell
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ The name of Russell McDonell shall not used to endorse or promote products
16
+ derived from this software without specific prior written permission.
17
+
18
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
+ SOFTWARE.
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 uengine (rickjang)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
@@ -0,0 +1,8 @@
1
+ include README_MCP.md
2
+ include LICENSE_MCP
3
+ include SETUP_GUIDE.md
4
+ include MCP_PROJECT_SUMMARY.md
5
+ include requirements_mcp.txt
6
+ include claude_desktop_config.json
7
+ recursive-include pydmnrules_mcp *.py
8
+
@@ -0,0 +1,399 @@
1
+ # pyDMNrules MCP Server - 프로젝트 요약
2
+
3
+ ## 프로젝트 개요
4
+
5
+ pyDMNrules 엔진을 사용하여 DMN (Decision Model Notation) XML 파일을 로드하고 의사결정을 실행하는 FastMCP 기반 MCP 서버입니다.
6
+
7
+ ### 주요 특징
8
+
9
+ ✅ **DMN XML 지원**: DMN 1.1/1.2/1.3 표준 XML 파일 로드 및 실행
10
+ ✅ **규칙 관리**: 저장, 로드, 삭제, 목록 조회
11
+ ✅ **스키마 자동 추출**: LLM이 이해할 수 있는 입력/출력 스키마 제공
12
+ ✅ **의사결정 추적**: 실행 경로 및 결과에 대한 상세 trace
13
+ ✅ **FastMCP 기반**: 안정적이고 빠른 MCP 서버
14
+
15
+ ## 프로젝트 구조
16
+
17
+ ```
18
+ pyDMNrules/
19
+ ├── pydmnrules_mcp_server.py # MCP 서버 메인 파일 ⭐
20
+ ├── requirements_mcp.txt # 의존성 목록
21
+ ├── README_MCP.md # 사용자 문서
22
+ ├── SETUP_GUIDE.md # 설정 가이드
23
+ ├── MCP_PROJECT_SUMMARY.md # 이 파일
24
+ ├── claude_desktop_config.json # Claude Desktop 설정 예제
25
+
26
+ ├── test_mcp_server.py # 기본 테스트
27
+ ├── test_mcp_with_simulation.py # 완전한 테스트 ⭐
28
+ ├── test_pydmnrules_direct.py # pyDMNrules 직접 테스트
29
+ ├── test_pydmnrules_direct2.py # pyDMNrules 직접 테스트 (수정)
30
+
31
+ ├── rules/ # DMN 규칙 저장 디렉토리
32
+ │ └── simulation.dmn # 예제 규칙
33
+
34
+ └── pyDMNrules/ # pyDMNrules 엔진
35
+ ├── __init__.py
36
+ └── DMNrules.py
37
+ ```
38
+
39
+ ## 핵심 파일 설명
40
+
41
+ ### 1. `pydmnrules_mcp_server.py` ⭐
42
+
43
+ MCP 서버의 메인 파일입니다. 다음을 포함합니다:
44
+
45
+ **클래스**:
46
+ - `PyDMNrulesEngine`: pyDMNrules 엔진을 감싸는 래퍼
47
+ - `DMNModel`: DMN 규칙 파일 관리
48
+ - `DecisionResult`: 의사결정 결과 데이터 모델
49
+
50
+ **MCP Tools (7개)**:
51
+ 1. `load_rule` - 규칙 로드
52
+ 2. `save_rule` - 규칙 저장
53
+ 3. `list_rules` - 규칙 목록
54
+ 4. `delete_rule` - 규칙 삭제
55
+ 5. `get_rule_schema` - 스키마 조회 (중요!)
56
+ 6. `infer_decision` - 의사결정 실행
57
+ 7. `check_engine_status` - 엔진 상태
58
+
59
+ ### 2. `test_mcp_with_simulation.py` ⭐
60
+
61
+ 완전한 기능 테스트 스크립트입니다. 다음을 테스트합니다:
62
+ - 규칙 저장/로드
63
+ - 스키마 조회
64
+ - 의사결정 실행 (3가지 시나리오)
65
+ - 결과 검증
66
+
67
+ ### 3. `requirements_mcp.txt`
68
+
69
+ 필수 의존성:
70
+ ```
71
+ fastmcp>=0.4.0
72
+ pydantic>=2.0.0
73
+ aiofiles>=23.0.0
74
+ pydmnrules-enhanced>=1.5.0
75
+ ```
76
+
77
+ ## 구현 세부사항
78
+
79
+ ### 핵심 기능
80
+
81
+ #### 1. DMN XML 로드
82
+ ```python
83
+ dmn_model = DMN()
84
+ status = dmn_model.useXML(xml_content)
85
+ ```
86
+
87
+ pyDMNrules의 `useXML()` 메서드를 사용하여 XML 문자열로부터 규칙을 로드합니다.
88
+
89
+ #### 2. 메타데이터 추출
90
+ ```python
91
+ def _extract_metadata(self, dmn_model: DMN, rule_name: str) -> Dict[str, Any]:
92
+ """
93
+ Glossary로부터 Variable 이름 추출
94
+ Decision Tables 정보 추출
95
+ 입력/출력 필드 정보 구성
96
+ """
97
+ ```
98
+
99
+ **중요**: pyDMNrules는 XML의 input label을 Variable 이름으로 사용합니다.
100
+ - XML: `<input label="Season">` → Variable: `"Season"`
101
+ - XML: `<input label="How many guests">` → Variable: `"How many guests"` (공백 포함!)
102
+
103
+ #### 3. 스키마 제공
104
+ ```python
105
+ {
106
+ "rule_name": "simulation",
107
+ "variable_names": ["Season", "How many guests", "Guests with children"],
108
+ "important_note": "⚠️ Use EXACT variable names...",
109
+ "inputs": {
110
+ "Season": {
111
+ "variable_name": "Season",
112
+ "feel_name": "Data.Season",
113
+ "type": "string",
114
+ "required": true
115
+ }
116
+ }
117
+ }
118
+ ```
119
+
120
+ LLM이 `variable_names`를 보고 정확한 키 이름을 사용할 수 있도록 합니다.
121
+
122
+ #### 4. 의사결정 실행
123
+ ```python
124
+ (status, result_data) = dmn_model.decide(input_context)
125
+ ```
126
+
127
+ pyDMNrules의 `decide()` 메서드를 호출하여 의사결정을 실행합니다.
128
+
129
+ #### 5. 결과 파싱
130
+ ```python
131
+ def _parse_result(self, result_data: Any) -> Dict[str, Any]:
132
+ """
133
+ 단일 decision 또는 여러 decision 처리
134
+ Result, Executed Rule, Annotations 추출
135
+ """
136
+ ```
137
+
138
+ ### 주요 도전과제 및 해결
139
+
140
+ #### 문제 1: Variable 이름 불일치
141
+
142
+ **문제**:
143
+ ```python
144
+ # ✗ 작동하지 않음
145
+ {"season": "Fall", "guestCount": 4}
146
+ ```
147
+
148
+ **원인**: pyDMNrules의 Glossary에는 XML의 정확한 label이 저장됨
149
+
150
+ **해결**:
151
+ ```python
152
+ # ✓ 작동함
153
+ {"Season": "Fall", "How many guests": 4}
154
+ ```
155
+
156
+ 스키마에 `variable_names` 리스트를 추가하고, `important_note`로 강조
157
+
158
+ #### 문제 2: 결과 구조 다양성
159
+
160
+ **문제**: pyDMNrules는 상황에 따라 다른 결과 구조 반환
161
+ - 단일 decision: `dict`
162
+ - 여러 decision: `list[dict]`
163
+
164
+ **해결**: `_parse_result()`에서 두 가지 경우 모두 처리
165
+
166
+ ```python
167
+ if isinstance(result_data, list):
168
+ return {
169
+ "final_result": all_results[-1],
170
+ "all_results": all_results,
171
+ "decision_count": len(all_results)
172
+ }
173
+ ```
174
+
175
+ #### 문제 3: Trace 정보 구성
176
+
177
+ **문제**: pyDMNrules의 결과에서 실행 경로 추출
178
+
179
+ **해결**: `_build_trace()`에서 `Executed Rule` 정보 파싱
180
+
181
+ ```python
182
+ if 'Executed Rule' in result_data:
183
+ executed_rule = result_data['Executed Rule']
184
+ # (description, table_name, rule_id) 튜플 파싱
185
+ ```
186
+
187
+ ## 테스트 결과
188
+
189
+ ### simulation.dmn 테스트 (성공 ✅)
190
+
191
+ ```bash
192
+ $ python3 test_mcp_with_simulation.py
193
+
194
+ 테스트 케이스 1: Fall, 4 guests, with children
195
+ ✓ 결과:
196
+ Dish: Spareribs
197
+ Beverages: ['Aecht Schlenkerla Rauchbier', 'Apple Juice']
198
+ ✓ Dish 일치
199
+
200
+ 테스트 케이스 2: Summer, 10 guests, no children
201
+ ✓ 결과:
202
+ Dish: Light Salad and a nice Steak
203
+ Beverages: ['Water']
204
+ ✓ Dish 일치
205
+
206
+ 테스트 케이스 3: Winter, 2 guests, no children
207
+ ✓ 결과:
208
+ Dish: Roastbeef
209
+ Beverages: ['Water']
210
+ ✓ Dish 일치
211
+ ```
212
+
213
+ ## 사용 예제
214
+
215
+ ### Claude와 함께 사용
216
+
217
+ #### 1. 스키마 확인 후 실행
218
+ ```
219
+ Claude, simulation 규칙의 스키마를 먼저 확인하고,
220
+ 가을에 4명이 방문하는데 아이가 있을 때 추천 요리와 음료를 알려줘.
221
+ ```
222
+
223
+ Claude가 자동으로:
224
+ 1. `get_rule_schema("simulation")` 호출
225
+ 2. Variable 이름 확인: "Season", "How many guests", "Guests with children"
226
+ 3. 올바른 형식으로 입력 구성:
227
+ ```python
228
+ {
229
+ "Season": "Fall",
230
+ "How many guests": 4,
231
+ "Guests with children": True
232
+ }
233
+ ```
234
+ 4. `infer_decision()` 호출
235
+ 5. 결과 해석 및 제시
236
+
237
+ #### 2. 새 규칙 생성
238
+ ```
239
+ 고객 등급(Gold, Silver, Bronze)과 구매 금액에 따라
240
+ 할인율을 결정하는 DMN 규칙을 만들어줘.
241
+ "discount_rules"로 저장해.
242
+ ```
243
+
244
+ Claude가:
245
+ 1. DMN XML 생성
246
+ 2. `save_rule("discount_rules", xml_content)` 호출
247
+ 3. 저장 확인
248
+
249
+ ## API 요약
250
+
251
+ ### Tool: `get_rule_schema` (가장 중요!)
252
+
253
+ **왜 중요한가?**
254
+ - LLM이 올바른 입력 형식을 알 수 있음
255
+ - Variable 이름의 정확한 철자/대소문자/공백 확인 가능
256
+ - FEEL 표현식 이름도 제공
257
+
258
+ **반환 예시**:
259
+ ```json
260
+ {
261
+ "rule_name": "simulation",
262
+ "engine_type": "pyDMNrules",
263
+ "variable_names": ["Season", "How many guests", "Guests with children"],
264
+ "important_note": "⚠️ Use EXACT variable names...",
265
+ "inputs": {
266
+ "Season": {
267
+ "variable_name": "Season",
268
+ "feel_name": "Data.Season",
269
+ "description": "Data.Data.Season",
270
+ "type": "string",
271
+ "required": true
272
+ }
273
+ },
274
+ "decision_tables": [
275
+ {"name": "Dish", "hit_policy": "U"},
276
+ {"name": "Beverages", "hit_policy": "C"}
277
+ ],
278
+ "example_input": {
279
+ "Season": null,
280
+ "How many guests": null,
281
+ "Guests with children": null
282
+ }
283
+ }
284
+ ```
285
+
286
+ ### Tool: `infer_decision`
287
+
288
+ **입력**:
289
+ ```python
290
+ {
291
+ "rule_name": "simulation",
292
+ "context_input": {
293
+ "Season": "Fall",
294
+ "How many guests": 4,
295
+ "Guests with children": True
296
+ }
297
+ }
298
+ ```
299
+
300
+ **출력**:
301
+ ```python
302
+ {
303
+ "result": {
304
+ "final_result": {
305
+ "Dish": "Spareribs",
306
+ "Beverages": ["Aecht Schlenkerla Rauchbier", "Apple Juice"]
307
+ },
308
+ "all_results": [...],
309
+ "decision_count": 2
310
+ },
311
+ "trace": [
312
+ {"step": 1, "action": "input", "data": {...}},
313
+ {"step": 2, "action": "decision_table", "table": "Dish", "rule_id": "Rule.1"},
314
+ {"step": 3, "action": "decision_table", "table": "Beverages", ...}
315
+ ],
316
+ "input_context": {...},
317
+ "rule_name": "simulation",
318
+ "execution_time": 0.0035,
319
+ "rule_schema": {...},
320
+ "engine_used": "pyDMNrules"
321
+ }
322
+ ```
323
+
324
+ ## 설정 방법
325
+
326
+ ### 1. 의존성 설치
327
+ ```bash
328
+ cd /Users/uengine/dmn_mcp/pyDMNrules
329
+ pip install -r requirements_mcp.txt
330
+ ```
331
+
332
+ ### 2. 테스트
333
+ ```bash
334
+ python3 test_mcp_with_simulation.py
335
+ ```
336
+
337
+ ### 3. Claude Desktop 설정
338
+
339
+ **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
340
+
341
+ ```json
342
+ {
343
+ "mcpServers": {
344
+ "pydmnrules": {
345
+ "command": "python3",
346
+ "args": [
347
+ "/Users/uengine/dmn_mcp/pyDMNrules/pydmnrules_mcp_server.py"
348
+ ]
349
+ }
350
+ }
351
+ }
352
+ ```
353
+
354
+ ### 4. Claude Desktop 재시작
355
+
356
+ ## 다음 단계
357
+
358
+ ### 개선 가능한 점
359
+
360
+ 1. **타입 정보 강화**
361
+ - 현재: 모든 타입을 "string"으로 표시
362
+ - 개선: DMN XML의 typeRef 활용
363
+
364
+ 2. **입력/출력 구분**
365
+ - 현재: 모든 Glossary 항목을 입력으로 간주
366
+ - 개선: Decision Table 분석하여 실제 입력만 표시
367
+
368
+ 3. **에러 메시지 개선**
369
+ - pyDMNrules의 에러를 더 친화적으로 변환
370
+
371
+ 4. **캐싱**
372
+ - 로드된 규칙을 메모리에 캐싱하여 성능 향상
373
+
374
+ 5. **Excel 지원**
375
+ - pyDMNrules는 Excel도 지원하므로 추가 가능
376
+
377
+ ## 결론
378
+
379
+ pyDMNrules MCP Server는 DMN XML 규칙을 LLM이 쉽게 사용할 수 있도록 하는 완전한 MCP 서버입니다.
380
+
381
+ **핵심 성공 요소**:
382
+ - ✅ pyDMNrules의 XML 로드 기능 활용
383
+ - ✅ Glossary에서 정확한 Variable 이름 추출
384
+ - ✅ LLM 친화적인 스키마 제공
385
+ - ✅ 상세한 실행 trace
386
+ - ✅ 포괄적인 테스트
387
+
388
+ **사용 준비 완료**:
389
+ - 모든 기능 테스트 완료
390
+ - 문서화 완료
391
+ - Claude Desktop 설정 가이드 제공
392
+
393
+ ---
394
+
395
+ **작성일**: 2025-10-19
396
+ **버전**: 1.0.0
397
+ **엔진**: pyDMNrules
398
+ **프레임워크**: FastMCP
399
+