콘텐츠로 이동
무료 평가 시작

MCP 서버

pdcomm-modbus-mcp는 Modbus 시뮬레이터를 MCP(Model Context Protocol) 서버로 제공합니다. Claude Code, Cursor 같은 AI 도구가 이 서버를 실행하고, 서비스 명령을 MCP 도구(tool)로 호출합니다. 명령과 결과는 헤드리스 시뮬레이터와 같습니다.

  • 전송은 stdio입니다. 표준 입력과 표준 출력으로 줄 단위 JSON-RPC 2.0 메시지를 주고받습니다.
  • 서버 프로세스 하나가 세션 하나입니다. 이미 켜 둔 GUI나 다른 프로세스의 상태를 보지 않습니다. 상태를 옮기려면 프로젝트 파일을 modbus_project_import로 불러오거나 실제 TCP로 통신합니다.
  • 서버 역할로 연결하면 MCP 서버가 입력을 기다리는 동안에도 요청에 응답합니다.

서버 명령은 SDK의 bin/pdcomm-modbus-mcp(Windows는 pdcomm-modbus-mcp.exe)의 절대 경로입니다. 인수는 없습니다.

프로젝트의 .mcp.json에 추가합니다.

.mcp.json
{
"mcpServers": {
"pdcomm-modbus": {
"type": "stdio",
"command": "/opt/pdcomm/pdcomm-modbus/bin/pdcomm-modbus-mcp"
}
}
}

세션에서 /mcp를 입력해 연결 상태를 확인합니다.

/opt/pdcomm/pdcomm-modbus는 예시 경로입니다. SDK를 푼 실제 경로로 바꿉니다. 진단 로그가 필요하면 클라이언트 설정의 env에 PDCOMM_LOG와 PDCOMM_LOG_FILE을 넣습니다. 로그는 표준 출력에 섞이지 않습니다.

서버는 서비스 명령마다 modbus_ 접두사를 붙인 도구 22개를 제공합니다. 도구의 arguments는 명령의 나머지 필드이며, action은 서버가 도구 이름으로 채웁니다.

도구 인수 예 하는 일
modbus_capabilities, modbus_state {} 빌드 기능, 현재 구성과 연결 상태
modbus_configure {"config":{...}} 구성 바꾸기(연결을 끊은 상태에서)
modbus_connect, modbus_disconnect {} 연결 열기와 닫기
modbus_request {"pdu":"0300000001","unit":1} 클라이언트 요청
modbus_execute {"pdu":"060000002A"} 로컬 모델에서 실행
modbus_data_get, modbus_data_set, modbus_model_set {"table":"holding_registers","address":0,"values":[1]} 데이터 모델 읽기와 바꾸기
modbus_diagnostics, modbus_diagnostics_set {} 진단 카운터와 레지스터
modbus_trace, modbus_trace_clear {} 요청·프레임 기록
modbus_project_export, modbus_project_import {"project":{...}} 프로젝트 저장과 불러오기
modbus_fault {"transport":"rtu","bytes":"01030000000AC5CD"} 합성 프레임 해석
modbus_serial_ports {} 직렬 포트 목록
modbus_poll {} 서버 한 번 처리(서버가 자동으로 하므로 보통 쓰지 않습니다)
modbus_logging_configure, modbus_logging_status, modbus_logging_flush {"config":{"level":"debug"}} 진단 로그 제어

각 명령의 필드는 JSON 명령 레퍼런스에 있습니다.

AI 도구 없이 직접 확인하려면 JSON-RPC 메시지를 한 줄씩 넣습니다.

터미널 창
"$MODBUS_SDK/bin/pdcomm-modbus-mcp"
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"tutorial","version":"1"}}}
{"jsonrpc":"2.0","method":"notifications/initialized"}
{"jsonrpc":"2.0","id":2,"method":"tools/list"}
{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"modbus_execute","arguments":{"pdu":"060000002A"}}}
{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"modbus_execute","arguments":{"pdu":"0300000001"}}}
{"jsonrpc":"2.0","id":5,"method":"tools/call","params":{"name":"modbus_request","arguments":{"pdu":"0300000001"}}}
{"jsonrpc":"2.0","id":6,"method":"tools/call","params":{"name":"modbus_execute","arguments":{"pdu":"0300000001","unit":300}}}
{"id":1,"jsonrpc":"2.0","result":{"capabilities":{"tools":{"listChanged":false}},"protocolVersion":"2025-11-25","serverInfo":{"name":"pdcomm-modbus","version":"1.0.0"}}}
{"id":2,"jsonrpc":"2.0","result":{"tools":[{"description":"Configure diagnostic logging.","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"config":{...}},"required":["config"],"type":"object"},"name":"modbus_logging_configure","title":"Configure logging"},...]}}
{"id":3,"jsonrpc":"2.0","result":{"content":[{"text":"{\"response\":[6,0,0,0,42],\"source\":\"local\",\"status\":\"success\"}","type":"text"}],"isError":false}}
{"id":4,"jsonrpc":"2.0","result":{"content":[{"text":"{\"response\":[3,2,0,42],\"source\":\"local\",\"status\":\"success\"}","type":"text"}],"isError":false}}
{"id":5,"jsonrpc":"2.0","result":{"content":[{"text":"Connect a client before sending a request","type":"text"}],"isError":true}}
{"id":6,"jsonrpc":"2.0","result":{"content":[{"text":"Invalid arguments: unit must be at most 255","type":"text"}],"isError":true}}
  • 알림(notifications/initialized)에는 응답이 없습니다.
  • 서버는 프로토콜 버전 2025-11-25, 2025-06-18, 2024-11-05를 받습니다. 그 밖의 버전을 요청하면 2025-11-25로 응답합니다.
  • 위 tools/list 응답은 줄였습니다. 도구마다 닫힌 입력 스키마(JSON Schema 2020-12)가 있고, 인자마다 형식, 범위, 설명을 담습니다.
  • 결과는 content[0].text에 JSON 문자열로 들어 있습니다. 클라이언트는 이 문자열을 다시 JSON으로 파싱합니다.
  • 입력 스키마에 맞지 않는 인자는 시뮬레이터에 전달되지 않습니다. 프로토콜 2025-11-25에서는 id 6의 응답처럼 isError와 Invalid arguments:로 시작하는 텍스트를 돌려줍니다. 2025-06-18과 2024-11-05에서는 JSON-RPC 오류 {"error":{"code":-32602,"message":"Invalid arguments: unit must be at most 255"},"id":6,"jsonrpc":"2.0"}를 돌려줍니다.
  • 입력을 닫으면 서버가 끝납니다.

MCP 응답의 실패는 네 층으로 나뉩니다.

층 모습 예
Modbus 예외 isError가 false, 결과의 status가 exception {"response":[131,2],...,"status":"exception"}
서비스 오류 isError가 true, text가 오류 메시지 Connect a client before sending a request, Timeout
잘못된 인자 프로토콜 2025-11-25에서는 isError가 true, 그 전 버전에서는 -32602 오류. 메시지는 Invalid arguments:로 시작 Invalid arguments: unit must be at most 255
JSON-RPC 오류 error 객체 -32700(JSON 파싱 실패), -32601(Unknown method or server is not initialized), -32602(Unknown tool: <이름>, Arguments must be an object)
  • initialize 전에 tools/list나 tools/call을 보내면 -32601입니다.
  • modbus_shutdown 같은 없는 도구는 -32602 Unknown tool: modbus_shutdown입니다.
  • JSON 파싱 오류가 있었으면 서버는 끝날 때 종료 코드 1을 돌려줍니다. 도구 호출의 isError는 종료 코드에 영향을 주지 않으므로, 프로세스 종료 코드만으로 모든 호출의 성공을 판단하지 않습니다.