# pyDMNrules MCP Server
**pyDMNrules-enhanced** 엔진을 사용하여 DMN XML 파일을 로드하고 의사결정을 실행하는 MCP (Model Context Protocol) 서버입니다.
[](https://badge.fury.io/py/pydmnrules-mcp-server)
[](https://www.python.org/downloads/)
[](https://opensource.org/licenses/MIT)
## 특징
- **DMN XML 지원**: DMN 1.1/1.2/1.3 표준 XML 파일 로드 및 실행
- **DRD 자동 매핑**: informationRequirement/requiredInput 자동 처리 (v1.1.0+)
- **규칙 관리**: DMN 규칙의 저장, 로드, 삭제, 목록 조회
- **스키마 자동 추출**: LLM이 이해할 수 있는 입력/출력 스키마 제공
- **의사결정 추적**: 실행된 규칙과 결과에 대한 상세한 trace 정보 제공
- **FastMCP 기반**: 빠르고 안정적인 MCP 서버 구현
- **pyDMNrules-enhanced v1.6.0**: DRD 지원이 추가된 향상된 엔진 사용
## 빠른 시작
### PyPI에서 설치 (권장) 🚀
```bash
pip install pydmnrules-mcp-server
```
이 명령 하나로 모든 의존성이 자동으로 설치됩니다!
### 개발 버전 설치
```bash
pip install -r requirements_mcp.txt
```
또는 개별 설치:
```bash
pip install fastmcp pydantic aiofiles pydmnrules-enhanced
```
### 2. 서버 실행 확인
```bash
# PyPI 설치 후
pydmnrules-mcp-server
# 또는 Python 모듈로
python -m pydmnrules_mcp.server
# 또는 개발 버전
python pydmnrules_mcp_server.py
```
## 사용법
### 서버 실행
```bash
# PyPI 설치 후 (가장 간단)
pydmnrules-mcp-server
# Python 모듈로
python -m pydmnrules_mcp.server
# 개발 버전
python pydmnrules_mcp_server.py
```
### Claude Desktop 설정
Claude Desktop에서 사용하려면 설정 파일에 추가하세요:
**macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
**Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
#### 방법 1: uvx 사용 (권장) ⭐
```json
{
"mcpServers": {
"pydmnrules": {
"command": "uvx",
"args": ["pydmnrules-mcp-server"]
}
}
}
```
**장점**:
- 설치 불필요
- 자동으로 격리된 환경에서 실행
- 빠른 속도
**사전 요구사항**: [uv 설치](https://github.com/astral-sh/uv)
```bash
# macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
```
자세한 내용: [UVX_SETUP_GUIDE.md](UVX_SETUP_GUIDE.md)
#### 방법 2: pip 설치 후 직접 실행
```json
{
"mcpServers": {
"pydmnrules": {
"command": "pydmnrules-mcp-server"
}
}
}
```
**사전 요구사항**: `pip install pydmnrules-mcp-server`
#### 방법 3: Python 모듈로 실행
```json
{
"mcpServers": {
"pydmnrules": {
"command": "python",
"args": ["-m", "pydmnrules_mcp.server"]
}
}
}
```
#### 방법 4: 개발 버전 사용
```json
{
"mcpServers": {
"pydmnrules": {
"command": "python",
"args": ["/path/to/pydmnrules_mcp_server.py"]
}
}
}
```
## MCP Tools
서버는 다음 6개의 tool을 제공합니다:
### 1. `load_rule`
저장된 DMN 규칙을 로드합니다.
**Parameters**:
- `rule_name` (string): 로드할 규칙의 이름 (확장자 제외)
**Returns**: 로드 결과 메시지
**Example**:
```python
load_rule(rule_name="discount_rules")
```
### 2. `save_rule`
새로운 DMN 규칙을 저장합니다.
**Parameters**:
- `rule_name` (string): 저장할 규칙의 이름
- `xml_content` (string): DMN XML 내용
**Returns**: 저장 결과 메시지
**Example**:
```python
save_rule(
rule_name="discount_rules",
xml_content="<?xml version='1.0' encoding='UTF-8'?>..."
)
```
### 3. `list_rules`
등록된 DMN 규칙 목록을 조회합니다.
**Returns**: 규칙 이름 목록
**Example**:
```python
rules = list_rules()
# Returns: ["discount_rules", "pricing_rules", ...]
```
### 4. `delete_rule`
DMN 규칙을 삭제합니다.
**Parameters**:
- `rule_name` (string): 삭제할 규칙의 이름
**Returns**: 삭제 결과 메시지
**Example**:
```python
delete_rule(rule_name="old_rules")
```
### 5. `get_rule_schema`
규칙의 입력/출력 스키마를 조회합니다. LLM이 올바른 형식으로 입력을 구성할 수 있도록 도와줍니다.
**Parameters**:
- `rule_name` (string): 규칙 이름
**Returns**: 스키마 정보 (inputs, outputs, decision_tables 등)
**Example**:
```python
schema = get_rule_schema(rule_name="discount_rules")
# Returns:
# {
# "rule_name": "discount_rules",
# "engine_type": "pyDMNrules",
# "inputs": {
# "Customer": {"description": "Customer.sector", "type": "string", "required": true},
# "OrderSize": {"description": "Order.orderSize", "type": "string", "required": true}
# },
# "outputs": {
# "Discount": {"description": "Discount.discount", "type": "string"}
# },
# "decision_tables": [
# {"name": "DiscountDecision", "hit_policy": "U", "description": "..."}
# ],
# "example_input": {
# "Customer": null,
# "OrderSize": null
# }
# }
```
### 6. `infer_decision`
DMN 규칙을 실행하여 의사결정을 수행합니다.
**Parameters**:
- `rule_name` (string): 사용할 DMN 규칙의 이름
- `context_input` (dict): key-value 딕셔너리 형태의 입력 데이터
**Returns**: 의사결정 결과
**Example**:
```python
result = infer_decision(
rule_name="discount_rules",
context_input={
"Customer": "Business",
"OrderSize": 15
}
)
# Returns:
# {
# "result": {
# "final_result": {"Discount": 0.15, ...},
# "all_results": [...],
# "decision_count": 1
# },
# "trace": [
# {"step": 1, "action": "input", "data": {...}},
# {"step": 2, "action": "decision_table", "table": "DiscountDecision", "rule_id": "1", ...}
# ],
# "input_context": {"Customer": "Business", "OrderSize": 15},
# "rule_name": "discount_rules",
# "execution_time": 0.023,
# "rule_schema": {...},
# "engine_used": "pyDMNrules"
# }
```
### 7. `check_engine_status`
엔진의 상태를 확인합니다.
**Returns**: 엔진 상태 정보
**Example**:
```python
status = check_engine_status()
# Returns:
# {
# "pydmnrules_available": true,
# "message": "pyDMNrules Engine - Available: True",
# "loaded_models": ["discount_rules", "pricing_rules"],
# "total_loaded_models": 2,
# "rules_directory": "/path/to/rules"
# }
```
## Claude와 함께 사용하기
### 1. DMN 규칙 저장
```
나에게 고객 유형과 주문 크기에 따라 할인율을 결정하는 DMN 규칙을 만들어줘.
그리고 "discount_rules"라는 이름으로 저장해줘.
```
Claude가 DMN XML을 생성하고 `save_rule`을 호출합니다.
### 2. 규칙 로드 및 스키마 확인
```
discount_rules의 입력 스키마를 보여줘.
```
Claude가 `get_rule_schema`를 호출하여 어떤 입력이 필요한지 확인합니다.
### 3. 의사결정 실행
```
고객이 "Business"이고 주문 크기가 15일 때 할인율을 계산해줘.
discount_rules를 사용해.
```
Claude가 적절한 형태로 입력을 구성하고 `infer_decision`을 호출합니다.
### 4. 규칙 관리
```
현재 저장된 모든 규칙을 보여줘.
```
Claude가 `list_rules`를 호출합니다.
## DMN XML 파일 형식
pyDMNrules는 다음 형식의 DMN XML 파일을 지원합니다:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="https://www.omg.org/spec/DMN/20191111/MODEL/"
xmlns:dmndi="https://www.omg.org/spec/DMN/20191111/DMNDI/"
xmlns:dc="http://www.omg.org/spec/DMN/20180521/DC/"
id="Definitions_discount"
name="Discount Decision"
namespace="http://camunda.org/schema/1.0/dmn">
<decision id="Decision_discount" name="Discount">
<decisionTable id="DecisionTable_discount">
<input id="Input_1" label="Customer">
<inputExpression id="InputExpression_1" typeRef="string">
<text>Customer</text>
</inputExpression>
</input>
<input id="Input_2" label="Order Size">
<inputExpression id="InputExpression_2" typeRef="number">
<text>OrderSize</text>
</inputExpression>
</input>
<output id="Output_1" label="Discount" name="discount" typeRef="number"/>
<rule id="Rule_1">
<inputEntry id="InputEntry_1">
<text>"Business"</text>
</inputEntry>
<inputEntry id="InputEntry_2">
<text>>= 10</text>
</inputEntry>
<outputEntry id="OutputEntry_1">
<text>0.15</text>
</outputEntry>
</rule>
<!-- More rules... -->
</decisionTable>
</decision>
</definitions>
```
## 예제
예제 DMN 파일들이 프로젝트 디렉토리에 포함되어 있습니다:
- `Example1.xlsx` - Excel 형식 DMN 규칙
- `ExampleHPV.xlsx` - HPV 검사 의사결정 규칙
- `Therapy.xlsx` - 치료 추천 규칙
- `simulation.dmn` - 시뮬레이션 DMN XML
Excel 파일을 사용하는 경우, pyDMNrules의 `load()` 메서드를 사용할 수 있습니다.
## 디렉토리 구조
```
pyDMNrules/
├── pydmnrules_mcp_server.py # MCP 서버 메인 파일
├── requirements_mcp.txt # 의존성 목록
├── README_MCP.md # 이 파일
├── rules/ # DMN 규칙 저장 디렉토리
│ ├── discount_rules.dmn
│ ├── pricing_rules.dmn
│ └── ...
└── pyDMNrules/ # pyDMNrules 엔진
└── DMNrules.py
```
## 트러블슈팅
### pyDMNrules를 찾을 수 없음
```bash
pip install pydmnrules-enhanced
```
### XML 파싱 에러
- DMN XML이 유효한지 확인하세요
- XML 네임스페이스가 올바른지 확인하세요
- pyDMNrules가 지원하는 DMN 버전(1.1/1.2/1.3)인지 확인하세요
### 규칙 실행 에러
- `get_rule_schema`로 필요한 입력 필드를 확인하세요
- 입력 데이터 타입이 스키마와 일치하는지 확인하세요
- Glossary의 Variable 이름과 일치하는지 확인하세요
## 라이선스
이 프로젝트는 pyDMNrules의 라이선스를 따릅니다.
## 관련 링크
- [pyDMNrules GitHub](https://github.com/russellmcdonell/pyDMNrules)
- [FastMCP](https://github.com/jlowin/fastmcp)
- [Model Context Protocol](https://modelcontextprotocol.io/)
Raw data
{
"_id": null,
"home_page": "https://github.com/uengine/pyDMNrules",
"name": "pydmnrules-mcp-server",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "dmn decision-model mcp model-context-protocol llm ai fastmcp claude",
"author": "uengine (rickjang)",
"author_email": "rick.jang@uengine.org",
"download_url": "https://files.pythonhosted.org/packages/ff/00/736b0982774624c0a427085bf2f06b5fcd63b36804dc627122820933fb78/pydmnrules_mcp_server-1.1.0.tar.gz",
"platform": null,
"description": "# pyDMNrules MCP Server\n\n**pyDMNrules-enhanced** \uc5d4\uc9c4\uc744 \uc0ac\uc6a9\ud558\uc5ec DMN XML \ud30c\uc77c\uc744 \ub85c\ub4dc\ud558\uace0 \uc758\uc0ac\uacb0\uc815\uc744 \uc2e4\ud589\ud558\ub294 MCP (Model Context Protocol) \uc11c\ubc84\uc785\ub2c8\ub2e4.\n\n[](https://badge.fury.io/py/pydmnrules-mcp-server)\n[](https://www.python.org/downloads/)\n[](https://opensource.org/licenses/MIT)\n\n## \ud2b9\uc9d5\n\n- **DMN XML \uc9c0\uc6d0**: DMN 1.1/1.2/1.3 \ud45c\uc900 XML \ud30c\uc77c \ub85c\ub4dc \ubc0f \uc2e4\ud589\n- **DRD \uc790\ub3d9 \ub9e4\ud551**: informationRequirement/requiredInput \uc790\ub3d9 \ucc98\ub9ac (v1.1.0+)\n- **\uaddc\uce59 \uad00\ub9ac**: DMN \uaddc\uce59\uc758 \uc800\uc7a5, \ub85c\ub4dc, \uc0ad\uc81c, \ubaa9\ub85d \uc870\ud68c\n- **\uc2a4\ud0a4\ub9c8 \uc790\ub3d9 \ucd94\ucd9c**: LLM\uc774 \uc774\ud574\ud560 \uc218 \uc788\ub294 \uc785\ub825/\ucd9c\ub825 \uc2a4\ud0a4\ub9c8 \uc81c\uacf5\n- **\uc758\uc0ac\uacb0\uc815 \ucd94\uc801**: \uc2e4\ud589\ub41c \uaddc\uce59\uacfc \uacb0\uacfc\uc5d0 \ub300\ud55c \uc0c1\uc138\ud55c trace \uc815\ubcf4 \uc81c\uacf5\n- **FastMCP \uae30\ubc18**: \ube60\ub974\uace0 \uc548\uc815\uc801\uc778 MCP \uc11c\ubc84 \uad6c\ud604\n- **pyDMNrules-enhanced v1.6.0**: DRD \uc9c0\uc6d0\uc774 \ucd94\uac00\ub41c \ud5a5\uc0c1\ub41c \uc5d4\uc9c4 \uc0ac\uc6a9\n\n## \ube60\ub978 \uc2dc\uc791\n\n### PyPI\uc5d0\uc11c \uc124\uce58 (\uad8c\uc7a5) \ud83d\ude80\n\n```bash\npip install pydmnrules-mcp-server\n```\n\n\uc774 \uba85\ub839 \ud558\ub098\ub85c \ubaa8\ub4e0 \uc758\uc874\uc131\uc774 \uc790\ub3d9\uc73c\ub85c \uc124\uce58\ub429\ub2c8\ub2e4!\n\n### \uac1c\ubc1c \ubc84\uc804 \uc124\uce58\n\n```bash\npip install -r requirements_mcp.txt\n```\n\n\ub610\ub294 \uac1c\ubcc4 \uc124\uce58:\n\n```bash\npip install fastmcp pydantic aiofiles pydmnrules-enhanced\n```\n\n### 2. \uc11c\ubc84 \uc2e4\ud589 \ud655\uc778\n\n```bash\n# PyPI \uc124\uce58 \ud6c4\npydmnrules-mcp-server\n\n# \ub610\ub294 Python \ubaa8\ub4c8\ub85c\npython -m pydmnrules_mcp.server\n\n# \ub610\ub294 \uac1c\ubc1c \ubc84\uc804\npython pydmnrules_mcp_server.py\n```\n\n## \uc0ac\uc6a9\ubc95\n\n### \uc11c\ubc84 \uc2e4\ud589\n\n```bash\n# PyPI \uc124\uce58 \ud6c4 (\uac00\uc7a5 \uac04\ub2e8)\npydmnrules-mcp-server\n\n# Python \ubaa8\ub4c8\ub85c\npython -m pydmnrules_mcp.server\n\n# \uac1c\ubc1c \ubc84\uc804\npython pydmnrules_mcp_server.py\n```\n\n### Claude Desktop \uc124\uc815\n\nClaude Desktop\uc5d0\uc11c \uc0ac\uc6a9\ud558\ub824\uba74 \uc124\uc815 \ud30c\uc77c\uc5d0 \ucd94\uac00\ud558\uc138\uc694:\n\n**macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`\n**Windows**: `%APPDATA%\\Claude\\claude_desktop_config.json`\n\n#### \ubc29\ubc95 1: uvx \uc0ac\uc6a9 (\uad8c\uc7a5) \u2b50\n\n```json\n{\n \"mcpServers\": {\n \"pydmnrules\": {\n \"command\": \"uvx\",\n \"args\": [\"pydmnrules-mcp-server\"]\n }\n }\n}\n```\n\n**\uc7a5\uc810**: \n- \uc124\uce58 \ubd88\ud544\uc694\n- \uc790\ub3d9\uc73c\ub85c \uaca9\ub9ac\ub41c \ud658\uacbd\uc5d0\uc11c \uc2e4\ud589\n- \ube60\ub978 \uc18d\ub3c4\n\n**\uc0ac\uc804 \uc694\uad6c\uc0ac\ud56d**: [uv \uc124\uce58](https://github.com/astral-sh/uv)\n```bash\n# macOS/Linux\ncurl -LsSf https://astral.sh/uv/install.sh | sh\n```\n\n\uc790\uc138\ud55c \ub0b4\uc6a9: [UVX_SETUP_GUIDE.md](UVX_SETUP_GUIDE.md)\n\n#### \ubc29\ubc95 2: pip \uc124\uce58 \ud6c4 \uc9c1\uc811 \uc2e4\ud589\n\n```json\n{\n \"mcpServers\": {\n \"pydmnrules\": {\n \"command\": \"pydmnrules-mcp-server\"\n }\n }\n}\n```\n\n**\uc0ac\uc804 \uc694\uad6c\uc0ac\ud56d**: `pip install pydmnrules-mcp-server`\n\n#### \ubc29\ubc95 3: Python \ubaa8\ub4c8\ub85c \uc2e4\ud589\n\n```json\n{\n \"mcpServers\": {\n \"pydmnrules\": {\n \"command\": \"python\",\n \"args\": [\"-m\", \"pydmnrules_mcp.server\"]\n }\n }\n}\n```\n\n#### \ubc29\ubc95 4: \uac1c\ubc1c \ubc84\uc804 \uc0ac\uc6a9\n\n```json\n{\n \"mcpServers\": {\n \"pydmnrules\": {\n \"command\": \"python\",\n \"args\": [\"/path/to/pydmnrules_mcp_server.py\"]\n }\n }\n}\n```\n\n## MCP Tools\n\n\uc11c\ubc84\ub294 \ub2e4\uc74c 6\uac1c\uc758 tool\uc744 \uc81c\uacf5\ud569\ub2c8\ub2e4:\n\n### 1. `load_rule`\n\n\uc800\uc7a5\ub41c DMN \uaddc\uce59\uc744 \ub85c\ub4dc\ud569\ub2c8\ub2e4.\n\n**Parameters**:\n- `rule_name` (string): \ub85c\ub4dc\ud560 \uaddc\uce59\uc758 \uc774\ub984 (\ud655\uc7a5\uc790 \uc81c\uc678)\n\n**Returns**: \ub85c\ub4dc \uacb0\uacfc \uba54\uc2dc\uc9c0\n\n**Example**:\n```python\nload_rule(rule_name=\"discount_rules\")\n```\n\n### 2. `save_rule`\n\n\uc0c8\ub85c\uc6b4 DMN \uaddc\uce59\uc744 \uc800\uc7a5\ud569\ub2c8\ub2e4.\n\n**Parameters**:\n- `rule_name` (string): \uc800\uc7a5\ud560 \uaddc\uce59\uc758 \uc774\ub984\n- `xml_content` (string): DMN XML \ub0b4\uc6a9\n\n**Returns**: \uc800\uc7a5 \uacb0\uacfc \uba54\uc2dc\uc9c0\n\n**Example**:\n```python\nsave_rule(\n rule_name=\"discount_rules\",\n xml_content=\"<?xml version='1.0' encoding='UTF-8'?>...\"\n)\n```\n\n### 3. `list_rules`\n\n\ub4f1\ub85d\ub41c DMN \uaddc\uce59 \ubaa9\ub85d\uc744 \uc870\ud68c\ud569\ub2c8\ub2e4.\n\n**Returns**: \uaddc\uce59 \uc774\ub984 \ubaa9\ub85d\n\n**Example**:\n```python\nrules = list_rules()\n# Returns: [\"discount_rules\", \"pricing_rules\", ...]\n```\n\n### 4. `delete_rule`\n\nDMN \uaddc\uce59\uc744 \uc0ad\uc81c\ud569\ub2c8\ub2e4.\n\n**Parameters**:\n- `rule_name` (string): \uc0ad\uc81c\ud560 \uaddc\uce59\uc758 \uc774\ub984\n\n**Returns**: \uc0ad\uc81c \uacb0\uacfc \uba54\uc2dc\uc9c0\n\n**Example**:\n```python\ndelete_rule(rule_name=\"old_rules\")\n```\n\n### 5. `get_rule_schema`\n\n\uaddc\uce59\uc758 \uc785\ub825/\ucd9c\ub825 \uc2a4\ud0a4\ub9c8\ub97c \uc870\ud68c\ud569\ub2c8\ub2e4. LLM\uc774 \uc62c\ubc14\ub978 \ud615\uc2dd\uc73c\ub85c \uc785\ub825\uc744 \uad6c\uc131\ud560 \uc218 \uc788\ub3c4\ub85d \ub3c4\uc640\uc90d\ub2c8\ub2e4.\n\n**Parameters**:\n- `rule_name` (string): \uaddc\uce59 \uc774\ub984\n\n**Returns**: \uc2a4\ud0a4\ub9c8 \uc815\ubcf4 (inputs, outputs, decision_tables \ub4f1)\n\n**Example**:\n```python\nschema = get_rule_schema(rule_name=\"discount_rules\")\n# Returns:\n# {\n# \"rule_name\": \"discount_rules\",\n# \"engine_type\": \"pyDMNrules\",\n# \"inputs\": {\n# \"Customer\": {\"description\": \"Customer.sector\", \"type\": \"string\", \"required\": true},\n# \"OrderSize\": {\"description\": \"Order.orderSize\", \"type\": \"string\", \"required\": true}\n# },\n# \"outputs\": {\n# \"Discount\": {\"description\": \"Discount.discount\", \"type\": \"string\"}\n# },\n# \"decision_tables\": [\n# {\"name\": \"DiscountDecision\", \"hit_policy\": \"U\", \"description\": \"...\"}\n# ],\n# \"example_input\": {\n# \"Customer\": null,\n# \"OrderSize\": null\n# }\n# }\n```\n\n### 6. `infer_decision`\n\nDMN \uaddc\uce59\uc744 \uc2e4\ud589\ud558\uc5ec \uc758\uc0ac\uacb0\uc815\uc744 \uc218\ud589\ud569\ub2c8\ub2e4.\n\n**Parameters**:\n- `rule_name` (string): \uc0ac\uc6a9\ud560 DMN \uaddc\uce59\uc758 \uc774\ub984\n- `context_input` (dict): key-value \ub515\uc154\ub108\ub9ac \ud615\ud0dc\uc758 \uc785\ub825 \ub370\uc774\ud130\n\n**Returns**: \uc758\uc0ac\uacb0\uc815 \uacb0\uacfc\n\n**Example**:\n```python\nresult = infer_decision(\n rule_name=\"discount_rules\",\n context_input={\n \"Customer\": \"Business\",\n \"OrderSize\": 15\n }\n)\n# Returns:\n# {\n# \"result\": {\n# \"final_result\": {\"Discount\": 0.15, ...},\n# \"all_results\": [...],\n# \"decision_count\": 1\n# },\n# \"trace\": [\n# {\"step\": 1, \"action\": \"input\", \"data\": {...}},\n# {\"step\": 2, \"action\": \"decision_table\", \"table\": \"DiscountDecision\", \"rule_id\": \"1\", ...}\n# ],\n# \"input_context\": {\"Customer\": \"Business\", \"OrderSize\": 15},\n# \"rule_name\": \"discount_rules\",\n# \"execution_time\": 0.023,\n# \"rule_schema\": {...},\n# \"engine_used\": \"pyDMNrules\"\n# }\n```\n\n### 7. `check_engine_status`\n\n\uc5d4\uc9c4\uc758 \uc0c1\ud0dc\ub97c \ud655\uc778\ud569\ub2c8\ub2e4.\n\n**Returns**: \uc5d4\uc9c4 \uc0c1\ud0dc \uc815\ubcf4\n\n**Example**:\n```python\nstatus = check_engine_status()\n# Returns:\n# {\n# \"pydmnrules_available\": true,\n# \"message\": \"pyDMNrules Engine - Available: True\",\n# \"loaded_models\": [\"discount_rules\", \"pricing_rules\"],\n# \"total_loaded_models\": 2,\n# \"rules_directory\": \"/path/to/rules\"\n# }\n```\n\n## Claude\uc640 \ud568\uaed8 \uc0ac\uc6a9\ud558\uae30\n\n### 1. DMN \uaddc\uce59 \uc800\uc7a5\n\n```\n\ub098\uc5d0\uac8c \uace0\uac1d \uc720\ud615\uacfc \uc8fc\ubb38 \ud06c\uae30\uc5d0 \ub530\ub77c \ud560\uc778\uc728\uc744 \uacb0\uc815\ud558\ub294 DMN \uaddc\uce59\uc744 \ub9cc\ub4e4\uc5b4\uc918.\n\uadf8\ub9ac\uace0 \"discount_rules\"\ub77c\ub294 \uc774\ub984\uc73c\ub85c \uc800\uc7a5\ud574\uc918.\n```\n\nClaude\uac00 DMN XML\uc744 \uc0dd\uc131\ud558\uace0 `save_rule`\uc744 \ud638\ucd9c\ud569\ub2c8\ub2e4.\n\n### 2. \uaddc\uce59 \ub85c\ub4dc \ubc0f \uc2a4\ud0a4\ub9c8 \ud655\uc778\n\n```\ndiscount_rules\uc758 \uc785\ub825 \uc2a4\ud0a4\ub9c8\ub97c \ubcf4\uc5ec\uc918.\n```\n\nClaude\uac00 `get_rule_schema`\ub97c \ud638\ucd9c\ud558\uc5ec \uc5b4\ub5a4 \uc785\ub825\uc774 \ud544\uc694\ud55c\uc9c0 \ud655\uc778\ud569\ub2c8\ub2e4.\n\n### 3. \uc758\uc0ac\uacb0\uc815 \uc2e4\ud589\n\n```\n\uace0\uac1d\uc774 \"Business\"\uc774\uace0 \uc8fc\ubb38 \ud06c\uae30\uac00 15\uc77c \ub54c \ud560\uc778\uc728\uc744 \uacc4\uc0b0\ud574\uc918.\ndiscount_rules\ub97c \uc0ac\uc6a9\ud574.\n```\n\nClaude\uac00 \uc801\uc808\ud55c \ud615\ud0dc\ub85c \uc785\ub825\uc744 \uad6c\uc131\ud558\uace0 `infer_decision`\uc744 \ud638\ucd9c\ud569\ub2c8\ub2e4.\n\n### 4. \uaddc\uce59 \uad00\ub9ac\n\n```\n\ud604\uc7ac \uc800\uc7a5\ub41c \ubaa8\ub4e0 \uaddc\uce59\uc744 \ubcf4\uc5ec\uc918.\n```\n\nClaude\uac00 `list_rules`\ub97c \ud638\ucd9c\ud569\ub2c8\ub2e4.\n\n## DMN XML \ud30c\uc77c \ud615\uc2dd\n\npyDMNrules\ub294 \ub2e4\uc74c \ud615\uc2dd\uc758 DMN XML \ud30c\uc77c\uc744 \uc9c0\uc6d0\ud569\ub2c8\ub2e4:\n\n```xml\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<definitions xmlns=\"https://www.omg.org/spec/DMN/20191111/MODEL/\"\n xmlns:dmndi=\"https://www.omg.org/spec/DMN/20191111/DMNDI/\"\n xmlns:dc=\"http://www.omg.org/spec/DMN/20180521/DC/\"\n id=\"Definitions_discount\"\n name=\"Discount Decision\"\n namespace=\"http://camunda.org/schema/1.0/dmn\">\n \n <decision id=\"Decision_discount\" name=\"Discount\">\n <decisionTable id=\"DecisionTable_discount\">\n <input id=\"Input_1\" label=\"Customer\">\n <inputExpression id=\"InputExpression_1\" typeRef=\"string\">\n <text>Customer</text>\n </inputExpression>\n </input>\n <input id=\"Input_2\" label=\"Order Size\">\n <inputExpression id=\"InputExpression_2\" typeRef=\"number\">\n <text>OrderSize</text>\n </inputExpression>\n </input>\n <output id=\"Output_1\" label=\"Discount\" name=\"discount\" typeRef=\"number\"/>\n \n <rule id=\"Rule_1\">\n <inputEntry id=\"InputEntry_1\">\n <text>\"Business\"</text>\n </inputEntry>\n <inputEntry id=\"InputEntry_2\">\n <text>>= 10</text>\n </inputEntry>\n <outputEntry id=\"OutputEntry_1\">\n <text>0.15</text>\n </outputEntry>\n </rule>\n \n <!-- More rules... -->\n </decisionTable>\n </decision>\n</definitions>\n```\n\n## \uc608\uc81c\n\n\uc608\uc81c DMN \ud30c\uc77c\ub4e4\uc774 \ud504\ub85c\uc81d\ud2b8 \ub514\ub809\ud1a0\ub9ac\uc5d0 \ud3ec\ud568\ub418\uc5b4 \uc788\uc2b5\ub2c8\ub2e4:\n\n- `Example1.xlsx` - Excel \ud615\uc2dd DMN \uaddc\uce59\n- `ExampleHPV.xlsx` - HPV \uac80\uc0ac \uc758\uc0ac\uacb0\uc815 \uaddc\uce59\n- `Therapy.xlsx` - \uce58\ub8cc \ucd94\ucc9c \uaddc\uce59\n- `simulation.dmn` - \uc2dc\ubbac\ub808\uc774\uc158 DMN XML\n\nExcel \ud30c\uc77c\uc744 \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0, pyDMNrules\uc758 `load()` \uba54\uc11c\ub4dc\ub97c \uc0ac\uc6a9\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.\n\n## \ub514\ub809\ud1a0\ub9ac \uad6c\uc870\n\n```\npyDMNrules/\n\u251c\u2500\u2500 pydmnrules_mcp_server.py # MCP \uc11c\ubc84 \uba54\uc778 \ud30c\uc77c\n\u251c\u2500\u2500 requirements_mcp.txt # \uc758\uc874\uc131 \ubaa9\ub85d\n\u251c\u2500\u2500 README_MCP.md # \uc774 \ud30c\uc77c\n\u251c\u2500\u2500 rules/ # DMN \uaddc\uce59 \uc800\uc7a5 \ub514\ub809\ud1a0\ub9ac\n\u2502 \u251c\u2500\u2500 discount_rules.dmn\n\u2502 \u251c\u2500\u2500 pricing_rules.dmn\n\u2502 \u2514\u2500\u2500 ...\n\u2514\u2500\u2500 pyDMNrules/ # pyDMNrules \uc5d4\uc9c4\n \u2514\u2500\u2500 DMNrules.py\n```\n\n## \ud2b8\ub7ec\ube14\uc288\ud305\n\n### pyDMNrules\ub97c \ucc3e\uc744 \uc218 \uc5c6\uc74c\n\n```bash\npip install pydmnrules-enhanced\n```\n\n### XML \ud30c\uc2f1 \uc5d0\ub7ec\n\n- DMN XML\uc774 \uc720\ud6a8\ud55c\uc9c0 \ud655\uc778\ud558\uc138\uc694\n- XML \ub124\uc784\uc2a4\ud398\uc774\uc2a4\uac00 \uc62c\ubc14\ub978\uc9c0 \ud655\uc778\ud558\uc138\uc694\n- pyDMNrules\uac00 \uc9c0\uc6d0\ud558\ub294 DMN \ubc84\uc804(1.1/1.2/1.3)\uc778\uc9c0 \ud655\uc778\ud558\uc138\uc694\n\n### \uaddc\uce59 \uc2e4\ud589 \uc5d0\ub7ec\n\n- `get_rule_schema`\ub85c \ud544\uc694\ud55c \uc785\ub825 \ud544\ub4dc\ub97c \ud655\uc778\ud558\uc138\uc694\n- \uc785\ub825 \ub370\uc774\ud130 \ud0c0\uc785\uc774 \uc2a4\ud0a4\ub9c8\uc640 \uc77c\uce58\ud558\ub294\uc9c0 \ud655\uc778\ud558\uc138\uc694\n- Glossary\uc758 Variable \uc774\ub984\uacfc \uc77c\uce58\ud558\ub294\uc9c0 \ud655\uc778\ud558\uc138\uc694\n\n## \ub77c\uc774\uc120\uc2a4\n\n\uc774 \ud504\ub85c\uc81d\ud2b8\ub294 pyDMNrules\uc758 \ub77c\uc774\uc120\uc2a4\ub97c \ub530\ub985\ub2c8\ub2e4.\n\n## \uad00\ub828 \ub9c1\ud06c\n\n- [pyDMNrules GitHub](https://github.com/russellmcdonell/pyDMNrules)\n- [FastMCP](https://github.com/jlowin/fastmcp)\n- [Model Context Protocol](https://modelcontextprotocol.io/)\n\n",
"bugtrack_url": null,
"license": null,
"summary": "MCP server for pyDMNrules-enhanced - enables LLMs to execute DMN decision rules with DRD support",
"version": "1.1.0",
"project_urls": {
"Documentation": "https://github.com/uengine/pyDMNrules/blob/master/README_MCP.md",
"Homepage": "https://github.com/uengine/pyDMNrules",
"Source": "https://github.com/uengine/pyDMNrules",
"Tracker": "https://github.com/uengine/pyDMNrules/issues"
},
"split_keywords": [
"dmn",
"decision-model",
"mcp",
"model-context-protocol",
"llm",
"ai",
"fastmcp",
"claude"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "af15b7632ddf51514f26ad60a7e5510405150bef1c27791a8349acfaa8f2c6b3",
"md5": "62630552f9a9d101f649a9f83ab6484f",
"sha256": "06ebf4f7ad069907b608cd2102b3240adb7b311dd7c2f005aa948b6683bca457"
},
"downloads": -1,
"filename": "pydmnrules_mcp_server-1.1.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "62630552f9a9d101f649a9f83ab6484f",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 13581,
"upload_time": "2025-10-20T03:20:42",
"upload_time_iso_8601": "2025-10-20T03:20:42.126390Z",
"url": "https://files.pythonhosted.org/packages/af/15/b7632ddf51514f26ad60a7e5510405150bef1c27791a8349acfaa8f2c6b3/pydmnrules_mcp_server-1.1.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "ff00736b0982774624c0a427085bf2f06b5fcd63b36804dc627122820933fb78",
"md5": "83ef66186a800d323a28aee2bf5c239a",
"sha256": "43c5ae26ecc532bd80e4cddc365f0d68ca9018117746be4ce42b690c9b65c8e8"
},
"downloads": -1,
"filename": "pydmnrules_mcp_server-1.1.0.tar.gz",
"has_sig": false,
"md5_digest": "83ef66186a800d323a28aee2bf5c239a",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 38926,
"upload_time": "2025-10-20T03:20:43",
"upload_time_iso_8601": "2025-10-20T03:20:43.870348Z",
"url": "https://files.pythonhosted.org/packages/ff/00/736b0982774624c0a427085bf2f06b5fcd63b36804dc627122820933fb78/pydmnrules_mcp_server-1.1.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-20 03:20:43",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "uengine",
"github_project": "pyDMNrules",
"github_not_found": true,
"lcname": "pydmnrules-mcp-server"
}