PLC控制协议服务器

BnR-MCP-Server是一个统一的模型上下文协议服务器,用于B&R Automation Studio,支持构建项目、连接PLC、读写变量、趋势数据、生成图表和查询本地变量数据库,可通过Claude或任何MCP兼容的AI助手使用。

  • by controlguy-ys
  • TypeScript
  • 本地部署
  • 3 星标
  • 更新于
在 GitHub 查看 googoles/br-automation-pvi-mcp-server

使用说明

BnR-MCP-Server

Unified MCP (Model Context Protocol) server for B&R Automation Studio — build projects, connect to PLCs, read/write variables, trend data, generate charts, and query a local variable database, all from Claude or any MCP-compatible AI assistant.

38 tools | TypeScript + C# companion | SQLite variable index | MIT License


Features

Category Tools Description
Build 4 Build AS6 projects, transfer to target, parse build logs
Connect 5 ANSL/TCP connection to PLC or ARSim, auto-detect, ping, switch target
Variables 4 Read/write scalars, structs, arrays, batch operations
Variable DB 3 SQLite-backed variable index — fast query without PLC round-trip
Watch 6 Poll variables, list sessions, export CSV, live web dashboard
Fast Trend 3 High-frequency monitoring (10-100ms) via C# companion + PNG charts
PLC Info 4 CPU info, task list, module list, error logbook
Modules 3 Upload/download/compare .br module files
Control 3 Coldstart, warmstart, diagnostics mode (with safety confirmation)
Workflow 2 One-shot deploy workflow, full health report

Prerequisites

Required

Dependency Version Purpose
B&R Automation Studio 6 AS6 Provides BR.AS.Build.exe and PVITransfer.exe
B&R PVI 6 PVI 6.x PLC communication runtime (installed with AS6)
Node.js 18+ MCP server runtime
npm 9+ Package manager

Optional (for high-frequency trending)

Dependency Version Purpose
.NET Framework 4.8.1 x86 Required by BR.AN.PviServices.dll
MSBuild / dotnet CLI .NET SDK 8.0+ Building the C# companion
Windows 10/11 PVIServices is Windows-only (x86)

Important: BR.AN.PviServices.dll is a PE32 (x86) .NET Framework assembly. It does not work under .NET 8.0 x64. The companion must target net481 with PlatformTarget=x86.

Auto-Detected Paths

The server auto-detects B&R installation paths. Override with environment variables if needed:

Component Default Locations
BR.AS.Build.exe C:\Program Files (x86)\BrAutomation\AS6\bin-en\BR.AS.Build.exe
PVITransfer.exe C:\Program Files (x86)\BrAutomation\PVI6\PVI\Tools\PVITransfer\PVITransfer.exe
PviCompanion.exe companion\bin\Release\net481\PviCompanion.exe (relative to project)

Installation

# Clone
git clone https://github.com/your-username/BnR-MCP-Server.git
cd BnR-MCP-Server

# Install dependencies
npm install

# Build TypeScript
npm run build

# (Optional) Build C# companion for high-frequency trending
npm run build:companion
# or manually:
dotnet build companion/PviCompanion.csproj -c Release

Configuration

Claude Desktop / Claude Code

Add to your MCP settings (claude_desktop_config.json or Claude Code settings):

{
  "mcpServers": {
    "bnr": {
      "command": "node",
      "args": ["C:/path/to/BnR-MCP-Server/dist/index.js"],
      "env": {
        "PVI_PLC_IP": "192.168.0.10",
        "BR_PROJECTS_ROOT": "C:/Users/you/projects"
      }
    }
  }
}

Environment Variables

All configuration is optional — sensible defaults are provided.

Variable Default Description
BR_BUILD_EXE (auto-detect) Path to BR.AS.Build.exe
BR_PROJECTS_ROOT Current directory Root directory for project scanning
BR_BUILD_TIMEOUT_MS 300000 (5 min) Build timeout in milliseconds
BR_EXCLUDED_DIRS node_modules,Temp,Binaries,.git Directories to skip when scanning
PVI_TRANSFER_EXE (auto-detect) Path to PVITransfer.exe
PVI_PLC_IP 192.168.0.10 Default PLC IP address
PVI_WAIT_TIME 30 Connection timeout in seconds
PVI_TEMP_DIR %TEMP%/pvi-mcp Temp directory for PIL scripts
PVI_WATCH_MAX_SAMPLES 3600 Max samples per watch session
PVI_COMPANION_EXE (auto-detect) Path to PviCompanion.exe
BNR_DB_PATH %TEMP%/pvi-mcp/bnr-mcp.db SQLite database path

Total Workflow

The complete development-to-debugging cycle using BnR-MCP-Server:

┌─────────────────────────────────────────────────────────────────────────┐
│                        TOTAL WORKFLOW                                  │
│                                                                       │
│  ┌─────────┐    ┌─────────┐    ┌─────────┐    ┌─────────┐            │
│  │ 1.SETUP │───▶│ 2.BUILD │───▶│3.CONNECT│───▶│ 4.DEBUG │            │
│  └─────────┘    └─────────┘    └─────────┘    └─────────┘            │
│       │              │              │              │                   │
│       ▼              ▼              ▼              ▼                   │
│  Install &      Build AS6      Connect to     Read/Write              │
│  Configure      Project        PLC/ARSim      Variables               │
│                                                    │                   │
│                                          ┌─────────▼─────────┐        │
│                                          │  5. VAR DATABASE  │        │
│                                          │  Refresh + Query  │        │
│                                          └─────────┬─────────┘        │
│                                                    │                   │
│  ┌─────────┐    ┌─────────┐    ┌─────────┐    ┌───▼─────┐            │
│  │9.CONTROL│◀───│8.EXPORT │◀───│ 7.CHART │◀───│ 6.TREND │            │
│  └─────────┘    └─────────┘    └─────────┘    └─────────┘            │
│       │              │              │              │                   │
│       ▼              ▼              ▼              ▼                   │
│  Restart PLC    CSV / Web       PNG Chart     Watch & Fast            │
│  Diagnostics    Dashboard       OxyPlot       Trend (10ms+)           │
│                                                                       │
└─────────────────────────────────────────────────────────────────────────┘

Step 1 — Setup

npm install && npm run build          # Build MCP server
npm run build:companion               # (Optional) Build C# companion

Add MCP server to Claude config → ready to use.

Step 2 — Build Project

"Build my project"
  → list_projects        Find .apj files in workspace
  → get_project_info     Check configurations
  → build_project        Build (mode: Build / Rebuild / BuildAndTransfer)
  → parse_build_log      Review errors & warnings
┌──────────────────────────────────────────────────────────────┐
│  AS6 Project (.apj)                                         │
│                                                             │
│  ┌─────────┐    ┌──────────────┐    ┌───────────────────┐   │
│  │ Sources │───▶│BR.AS.Build.exe│───▶│ Build Output      │   │
│  │ .st .c  │    │              │    │ ✓ 0 = Success     │   │
│  └─────────┘    │ -buildMode   │    │ ⚠ 1 = Warnings   │   │
│                 │  "Build"     │    │ ✗ 3 = Errors      │   │
│                 │  "Rebuild"   │    └───────────────────┘   │
│                 │  "BuildAnd   │             │               │
│                 │   Transfer"  │             ▼               │
│                 └──────────────┘    ┌───────────────────┐   │
│                                    │ parse_build_log    │   │
│                                    │ → structured JSON  │   │
│                                    └───────────────────┘   │
└──────────────────────────────────────────────────────────────┘

BuildAndTransfer — builds the project and transfers the installation package to the connected target (ARSim or real PLC). This is the B&R standard "Transfer to target" mechanism:

Sources → BUILD → Modules (.br) → PACK → Installation Package → TRANSFER → PLC

Step 3 — Connect to PLC

"Connect to my PLC"
  → pvi_ping             Quick TCP probe to check reachability (~2s)
  → pvi_auto_connect     Try hardware PLC first (if PVI_PLC_IP set), then ARSim
  → pvi_connect          Manual: specify IP address
  → pvi_switch_target    Switch between hardware PLC and ARSim in one call
  → get_config           Verify paths and connection state
┌───────────────────────────────────────────────────────────────┐
│  Connection Flow (pvi_auto_connect with PVI_PLC_IP set)      │
│                                                              │
│       ├──▶ Try PVI_PLC_IP (hardware) ──────▶ Connected?      │
│       │         │                              │             │
│       │         │ No                          Yes ──▶ Done   │
│       │         ▼                                            │
│       └──▶ Try 127.0.0.1:11169 (ARSim) ──▶ Connected?       │
│                                               │              │
│                                   Yes ──▶ Done │              │
│                                                              │
│  Response: CPU type, AR version, PLC status, IP source       │
└───────────────────────────────────────────────────────────────┘

Step 4 — Debug (Read/Write Variables)

"What is the current temperature?"
  → pvi_read_variable            Read single variable (scalar/struct/array)
  → pvi_write_variable           Write single variable with read-back
  → pvi_write_variables_batch    Write multiple variables at once
┌─────────────────────────────────────────────────────────────────┐
│  Variable Access Patterns                                      │
│                                                                │
│  Scalar:    pvi_read_variable { name: "gTemperature" }         │
│                                                                │
│  Struct:    pvi_read_variable { name: "stSensor",              │
│                                 member: "rValue",              │
│                                 task: "Control" }              │
│                                                                │
│  Array:     pvi_read_variable { name: "aValues", index: 3 }   │
│                                                                │
│  Nested:    pvi_read_variable { name: "stBatch",               │
│                                 member: "aSensors[0].rValue" } │
│                                                                │
│  Batch:     pvi_write_variables_batch {                        │
│               variables: [                                     │
│                 { name: "gSetpoint", value: "75.0" },          │
│                 { name: "gMode",     value: "2"    }           │
│               ]                                                │
│             }                                                  │
└─────────────────────────────────────────────────────────────────┘

Step 5 — Variable Database (SQLite Index)

Build a local variable index for fast, offline querying without hitting the PLC each time.

"Show me all REAL variables in HMIMain"
  → pvi_refresh_variables    Fetch variables from PLC → store in SQLite
  → pvi_query_variables      Fast SQL query (no PLC round-trip)
  → pvi_db_status            Check DB health and last refresh time
┌──────────────────────────────────────────────────────────────────┐
│  Variable Database Workflow                                     │
│                                                                 │
│  Once:   pvi_refresh_variables { scope: "all" }                 │
│              → fetches globals (VariableListGlobal)             │
│          pvi_refresh_variables { scope: "local",                │
│                                  task: "HMIMain" }              │
│              → fetches task-local variables                     │
│                                                                 │
│  Anytime (fast):                                                │
│          pvi_query_variables { namePattern: "Reactor",          │
│                                dataTypeFilter: ["REAL"],        │
│                                task: "HMIMain",                 │
│                                limit: 50 }                      │
│              → SQL query, returns in <10ms                      │
│                                                                 │
│  SQLite DB: %TEMP%/pvi-mcp/bnr-mcp.db (persists across         │
│             server restarts, overridable via BNR_DB_PATH)       │
└──────────────────────────────────────────────────────────────────┘

Note: VariableListAll from PVITransfer only returns global-scope variables. For task-local variables (e.g. program variables in Module_0.var), run pvi_refresh_variables with scope: "local" and the specific task name.

Step 6 — Trend (Monitor Over Time)

Two trending engines available — choose based on speed requirements:

┌────────────────────────────────────────────────────────────────┐
│                                                               │
│  PVITransfer Trending (500ms+)     C# Companion (10-100ms)   │
│  ─────────────────────────────     ────────────────────────   │
│  pvi_watch_variables               pvi_fast_watch             │
│  pvi_get_trend_data                pvi_fast_trend_chart       │
│  pvi_stop_watch                    pvi_fast_stop              │
│  pvi_list_watch_sessions                                      │
│                                                               │
│  ┌──────────┐  spawn    ┌───────────────┐  persistent conn   │
│  │ Node.js  │─────────▶ │PVITransfer.exe│ ────▶ PLC          │
│  │ (poll)   │  per read │ (one-shot)    │                    │
│  └──────────┘           └───────────────┘                    │
│       vs.                                                     │
│  ┌──────────┐  stdin/   ┌───────────────┐  event-driven      │
│  │ Node.js  │──stdout──▶│PviCompanion   │ ────▶ PLC          │
│  │ (IPC)    │  JSON     │ .exe (x86)    │  PVIServices       │
│  └──────────┘           └───────────────┘                    │
│                                                               │
└────────────────────────────────────────────────────────────────┘
"Monitor temperature every 500ms for 30 seconds"
  → pvi_watch_variables    Start polling
  → (wait 30 seconds)
  → pvi_get_trend_data     Retrieve time-series data
  → pvi_stop_watch         Stop session (samples persisted to SQLite)

"Fast-trend 4 variables at 100ms"
  → pvi_fast_watch         Start C# companion monitoring
  → pvi_fast_trend_chart   Generate PNG chart
  → pvi_fast_stop          Stop session

Session persistence: When you call pvi_stop_watch, all samples are flushed to the SQLite DB. If the server restarts, pvi_get_trend_data and pvi_export_csv automatically fall back to the DB for stopped sessions. pvi_list_watch_sessions shows both active (in-memory) and historical (SQLite) sessions.

Step 7 — Chart (Visualize)

┌─────────────────────────────────────────────────────────────┐
│  Visualization Options                                     │
│                                                            │
│  ┌─────────────────┐    ┌──────────────────────────────┐   │
│  │ pvi_fast_trend   │    │ pvi_dashboard                │   │
│  │ _chart           │    │                              │   │
│  │                  │    │  ┌────────────────────────┐  │   │
│  │  OxyPlot PNG     │    │  │  Chart.js Live View    │  │   │
│  │  ┌────────────┐  │    │  │  localhost:3333        │  │   │
│  │  │ ╱╲  ╱╲     │  │    │  │                        │  │   │
│  │  │╱  ╲╱  ╲╱╲  │  │    │  │  Auto-refresh 1s      │  │   │
│  │  │          ╲  │  │    │  │  Multi-variable       │  │   │
│  │  └────────────┘  │    │  └────────────────────────┘  │   │
│  │  Base64 PNG      │    │  Open in browser             │   │
│  │  in MCP response │    │                              │   │
│  └─────────────────┘    └──────────────────────────────┘   │
│                                                            │
└─────────────────────────────────────────────────────────────┘

Step 8 — Export

"Export the trend data"
  → pvi_export_csv       Save to CSV file (timestamp + variable columns)
  → pvi_dashboard        Or open live web dashboard in browser

CSV output:
  timestamp,gTemperature,gPressure,gFlowRate
  2026-03-22T10:00:00.123,72.5,1.013,15.2
  2026-03-22T10:00:00.623,72.8,1.014,15.1
  ...

Both pvi_export_csv and pvi_get_trend_data fall back to SQLite automatically if the session is no longer in memory.

Step 9 — PLC Control & Diagnostics

"Check PLC status and restart"
  → pvi_get_cpu_info       CPU type, AR version, memory, status
  → pvi_list_tasks         All running tasks with versions
  → pvi_list_modules       All modules (system + application)
  → pvi_read_error_log     Error logbook entries
  → pvi_warmstart          Warm restart (preserves retained vars)
  → pvi_coldstart          Cold restart (clears non-retained vars)
  → pvi_diagnostics        Enter diagnostics mode

End-to-End Example (Natural Language)

You:    "Build ECELL_Base and transfer to ARSim"
Claude: → build_project (BuildAndTransfer, simulation=true)
        ✓ Build succeeded (0 errors, 2 warnings)
        ✓ Transferred to ARSim

You:    "Connect and show me what's running"
Claude: → pvi_ping          → reachable (3ms)
        → pvi_auto_connect  → Connected to hardware PLC (192.168.10.50)
        → pvi_get_cpu_info  → AR V6.5.1, CPU: 4PPC80.156B-13B
        → pvi_list_tasks    → 40 tasks running

You:    "Index all HMIMain variables"
Claude: → pvi_refresh_variables { scope: "local", task: "HMIMain" }
        ✓ 2121 variables indexed to SQLite

You:    "Find all REAL variables related to temperature"
Claude: → pvi_query_variables { namePattern: "Temp", dataTypeFilter: ["REAL"] }
        → 12 matches returned instantly (no PLC round-trip)

You:    "Watch temperature and pH for 1 minute"
Claude: → pvi_watch_variables { variables: [...], intervalMs: 500 }
        → (collecting samples over 60 seconds...)
        → pvi_get_trend_data
        → Temperature: 25.1°C, pH: 6.8

You:    "Export that to CSV"
Claude: → pvi_stop_watch  → samples flushed to SQLite
        → pvi_export_csv  → saved to C:/data/trend.csv

You:    "Warm restart the PLC"
Claude: → pvi_warmstart { confirm: true }
        ✓ PLC warm restarted — retained variables preserved

Usage Reference

Connect

pvi_ping             → { mode: "tcp" }            # fast probe (~2s)
pvi_auto_connect     → {}                         # auto-detect hardware/ARSim
pvi_connect          → { ipAddress: "192.168.0.10" }
pvi_switch_target    → { target: "arsim" }        # or "hardware"

Variable Database

pvi_refresh_variables → { scope: "all" }                        # globals
pvi_refresh_variables → { scope: "local", task: "HMIMain" }     # task-local
pvi_query_variables   → { namePattern: "Reactor", limit: 50 }
pvi_query_variables   → { dataTypeFilter: ["REAL", "BOOL"], task: "HMIMain" }
pvi_db_status         → {}                                       # count + last refresh

Read/Write Variables

pvi_read_variable    → { name: "gTemperature" }
pvi_read_variable    → { name: "stSensor", member: "rValue", task: "MainTask" }
pvi_read_variable    → { name: "aValues", index: 3 }
pvi_write_variable   → { name: "gSetpoint", value: "75.5", dataType: "REAL" }

Trend Data

pvi_watch_variables  → { variables: [...], intervalMs: 500 }
pvi_get_trend_data   → { watchId: "...", lastN: 100 }
pvi_export_csv       → { watchId: "...", filePath: "C:/data/trend.csv" }
pvi_list_watch_sessions → {}                      # active + SQLite history
pvi_stop_watch       → { watchId: "..." }         # flushes to SQLite
pvi_dashboard        → { watchId: "..." }         # opens Chart.js at localhost:3333

High-Frequency Trending (C# Companion)

pvi_fast_watch       → { variables: [...], intervalMs: 100 }
pvi_fast_trend_chart → { watchId: "..." }         # generates PNG chart via OxyPlot
pvi_fast_stop        → { watchId: "..." }

PLC Control (requires confirm: true)

pvi_warmstart        → { confirm: true }
pvi_coldstart        → { confirm: true }
pvi_diagnostics      → { confirm: true }

All 38 Tools

# Tool Category Description
1 build_project Build Build AS6 project (Build / Rebuild / BuildAndTransfer)
2 list_projects Build Scan directory for .apj project files
3 get_project_info Build Read project metadata and configurations
4 parse_build_log Build Parse build output into structured errors/warnings
5 pvi_connect Connect Connect to PLC via ANSL/TCP
6 pvi_disconnect Connect Disconnect and clear connection state
7 pvi_auto_connect Connect Auto-detect hardware PLC (PVI_PLC_IP) or ARSim
8 pvi_ping Connect TCP or full PVI reachability check
9 pvi_switch_target Connect Switch between hardware PLC and ARSim in one call
10 get_config Connect Show current server configuration and companion status
11 pvi_read_variable Variables Read scalar, struct member, or array element
12 pvi_write_variable Variables Write a single variable with read-back confirmation
13 pvi_list_variables Variables List all/global/local variables with values (PLC round-trip)
14 pvi_write_variables_batch Variables Write multiple variables in one operation
15 pvi_refresh_variables Variable DB Fetch variables from PLC and store in SQLite
16 pvi_query_variables Variable DB Fast SQL query against local variable index
17 pvi_db_status Variable DB Show DB path, variable count, last refresh time
18 pvi_watch_variables Watch Start polling variables at interval (500ms+)
19 pvi_get_trend_data Watch Get collected time-series data (in-memory or SQLite fallback)
20 pvi_stop_watch Watch Stop a watch session and flush samples to SQLite
21 pvi_list_watch_sessions Watch List all sessions — active (memory) + historical (SQLite)
22 pvi_export_csv Watch Export trend data to CSV file (in-memory or SQLite fallback)
23 pvi_dashboard Watch Live web dashboard with Chart.js (auto-refresh 1s)
24 pvi_fast_watch Fast Trend High-frequency monitoring (10-100ms) via C# companion
25 pvi_fast_trend_chart Fast Trend Generate PNG trend chart via OxyPlot
26 pvi_fast_stop Fast Trend Stop fast watch session
27 pvi_get_cpu_info PLC Info CPU type, AR version, memory, hardware
28 pvi_list_tasks PLC Info List all running tasks
29 pvi_list_modules PLC Info List all modules (system + application)
30 pvi_read_error_log PLC Info Read PLC error logbook
31 pvi_download_module Modules Transfer .br file PC → PLC
32 pvi_upload_module Modules Transfer module PLC → PC
33 pvi_check_module Modules Compare local vs PLC module version
34 pvi_coldstart Control Cold restart (clears non-retained variables)
35 pvi_warmstart Control Warm restart (preserves retained variables)
36 pvi_diagnostics Control Enter diagnostics mode (stops tasks)
37 pvi_deploy_workflow Workflow Build + transfer + connect in one call
38 pvi_health_report Workflow Full PLC health check (CPU, tasks, modules, errors)

Architecture

┌─────────────────────────────────────────────────────┐
│  Claude / MCP Client                                │
└──────────────────┬──────────────────────────────────┘
                   │ MCP Protocol (stdio)
┌──────────────────▼──────────────────────────────────┐
│  BnR-MCP-Server  (Node.js / TypeScript)             │
│                                                     │
│  ┌────────┐ ┌──────────┐ ┌───────┐ ┌───────────┐   │
│  │ Build  │ │Variables │ │Watch  │ │ Control   │   │
│  │ tools  │ │ tools    │ │tools  │ │ tools     │   │
│  └───┬────┘ └────┬─────┘ └───┬───┘ └─────┬─────┘   │
│      │           │           │            │         │
│  ┌───▼───────────▼───────────▼────────────▼──────┐  │
│  │  PIL Generator → PVITransfer.exe → Parser    │  │
│  └──────────────────────────────────────────────┘  │
│      │                                             │
│  ┌───▼──────────────────────┐  ┌────────────────┐  │
│  │  SQLite DB (bnr-mcp.db) │  │ C# Companion   │  │
│  │  • pvi_variables         │  │ (optional)     │  │
│  │  • watch_sessions        │  │ PviCompanion   │  │
│  │  • trend_samples         │  │ .exe (x86)     │  │
│  └──────────────────────────┘  │ PVIServices +  │  │
│                                │ OxyPlot        │  │
│                                └────────────────┘  │
└──────────────────┬──────────────────────────────────┘
                   │ ANSL/TCP (port 11169)
┌──────────────────▼──────────────────────────────────┐
│  B&R PLC  or  ARSim                                 │
└─────────────────────────────────────────────────────┘

SQLite Database Schema

-- Variable index (populated by pvi_refresh_variables)
pvi_variables (id, name, task, scope, data_type, size, last_value, updated_at)

-- Watch session metadata (written on start/stop)
watch_sessions (id, variables, interval_ms, max_samples, started_at, stopped_at)

-- Trend samples (flushed from memory on pvi_stop_watch)
trend_samples (id, session_id, ts, sample_values)

Restrictions & Known Limitations

PVITransfer-Based Tools

  • Polling interval minimum is ~500ms (PVITransfer process spawn overhead)
  • ReadVariable file output can return empty for some data types — use pvi_list_variables as fallback
  • Module download on ARSim fails with PVI Error #11156 — use build_project with BuildAndTransfer mode instead
  • PIL script execution is sequential — each tool call spawns a new PVITransfer.exe process
  • VariableListAll scope — returns global-scope variables only; use scope: "local" with a task name for program-local variables

C# Companion (Fast Trending)

  • Windows-only — BR.AN.PviServices.dll is a Windows x86 assembly
  • .NET Framework 4.8.1 required — .NET 8.0 x64 causes silent communication failures
  • Local task variables get PVI Error 11033 via PVIServices Variable objects — only global variables are supported for fast trending. Use PVITransfer-based pvi_watch_variables for local variables
  • WinForms message pump required — [STAThread] + Application.Run() needed for PVI event delivery

PLC Control

  • pvi_coldstart, pvi_warmstart, pvi_diagnostics require explicit confirm: true parameter
  • No undo — restart commands take effect immediately
  • Not recommended on production systems without operator awareness

General

  • Single connection — one PLC connection at a time
  • No OPC UA — communication is via PVI/ANSL only
  • No real-time guarantees — trending timestamps are approximate (depends on OS scheduling)
  • Temp files — PIL scripts and output files are created in PVI_TEMP_DIR and cleaned up after use

Project Structure

BnR-MCP-Server/
├── src/
│   ├── index.ts                 # MCP server entry — 38 tools registered
│   ├── tools/
│   │   ├── build.ts             # build_project, list_projects, get_project_info, parse_build_log
│   │   ├── connect.ts           # pvi_connect, pvi_disconnect, pvi_auto_connect, pvi_ping,
│   │   │                        #   pvi_switch_target, get_config
│   │   ├── control.ts           # pvi_coldstart, pvi_warmstart, pvi_diagnostics
│   │   ├── logs.ts              # pvi_read_error_log
│   │   ├── modules.ts           # pvi_download/upload/check_module
│   │   ├── plcinfo.ts           # pvi_get_cpu_info, pvi_list_tasks, pvi_list_modules
│   │   ├── projects.ts          # Project scanning utilities
│   │   ├── trending.ts          # pvi_fast_watch, pvi_fast_trend_chart, pvi_fast_stop
│   │   ├── vardb.ts             # pvi_refresh_variables, pvi_query_variables, pvi_db_status
│   │   ├── variables.ts         # pvi_read/write/list_variables, pvi_write_variables_batch
│   │   ├── watch.ts             # pvi_watch/get_trend/stop/list_sessions, pvi_export_csv,
│   │   │                        #   pvi_dashboard
│   │   └── workflow.ts          # pvi_deploy_workflow, pvi_health_report
│   ├── types/
│   │   ├── build.ts             # Build-related type definitions
│   │   └── pvi.ts               # PVI-related type definitions
│   └── utils/
│       ├── build-parser.ts      # Parse BR.AS.Build.exe output
│       ├── build-runner.ts      # Execute build commands
│       ├── companion.ts         # C# companion process manager
│       ├── config.ts            # Environment config + auto-detection
│       ├── connection-state.ts  # Global PLC connection state
│       ├── db.ts                # SQLite helpers (variables, watch sessions, trend samples)
│       ├── parsers.ts           # PVITransfer output parsers
│       ├── pil-generator.ts     # PIL script generator
│       ├── pvi-runner.ts        # PVITransfer.exe executor
│       ├── tool-helpers.ts      # Shared helpers (notConnectedError, etc.)
│       └── trend-buffer.ts      # In-memory trend data buffer
├── companion/
│   ├── PviCompanion.csproj      # .NET Framework 4.8.1 (x86)
│   ├── Program.cs               # Entry point + JSON IPC
│   ├── PviClient.cs             # PVIServices wrapper
│   └── ChartGenerator.cs        # OxyPlot PNG chart generation
├── package.json
└── tsconfig.json

Development

# Build TypeScript (watch mode not available — rebuild manually)
npm run build

# Build C# companion
npm run build:companion

# Start server directly (for testing)
npm start

# Test with ARSim
# 1. Open your project in Automation Studio
# 2. Start ARSim: Online → Simulation
# 3. Transfer project: Online → Transfer to target
# 4. The MCP server will auto-detect ARSim on localhost

License

MIT

Author

Yunsoo Jang (장윤수)