
EPICS Channel Access
io.github.K-Dense-AIPublished by GitHub account K-Dense-AIv0.1.2Updated Nov 10, 2026
MCP server for EPICS Channel Access: read, monitor and guarded writes of process variables.
Overview
Lets an assistant read, monitor and, when explicitly allowed, carefully write EPICS process variables over Channel Access on lab control systems.
- What you can do
- Read PVs with metadata: value, units, alarm severity, timestamps, limits and enum names, singly or in bulk
- Monitor a PV for a set duration and return statistics such as min/max/mean and drift rate
- Inspect PV connection details, access rights and allow-list status, plus connection info and a raw command log
- Write one or several PVs with allow-list, access-rights, type and control-limit validation and read-back
- Apply a scientist-configured safe state and reconnect after power cycles or cable changes
- When to use it
- Useful for beamline, accelerator, telescope or lab staff who want an agent to check readings, watch for drift or alarms, and perform narrowly authorised setpoint changes on EPICS IOCs. Try the built-in simulator first to evaluate it without hardware.
- Requirements
- Runs locally as a Python package (uvx labmcp-epics). Network reachability to the IOCs or the facility CA gateway: UDP 5064/5065 and TCP 5064. Address list via EPICS_CA_ADDR_LIST or the address option; optional environment variables LABMCP_ADDRESS, LABMCP_LIMITS, LABMCP_READ_ONLY and LABMCP_SIMULATE. No authentication is declared.
Installation
In SourceWeft
- Open EPICS Channel Access in the dashboard and add it to a workspace.
- Enable the server for the chats that should use its tools.
Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.
Other MCP clients
Follow the launch instructions in the repository.
README
EPICS Channel Access — MCP Server
Let an AI agent read, monitor and, when you allow it, carefully write EPICS process variables (PVs) over Channel Access. EPICS is the control system behind most particle accelerators, synchrotron and neutron beamlines, large telescopes, fusion experiments and many physics labs. The server uses caproto, a pure-Python CA implementation, so there is nothing to compile and no libca to install.
⚠️ Facility control systems are safety-critical. Writing a PV can move motors and sample stages, open shutters, ramp magnets or high voltage, and change cryogenic or vacuum systems. Follow your facility's rules. Get authorisation from the responsible scientist or control-room staff before enabling writes, and run with
--read-onlyunless writes are explicitly authorised. This server is not an interlock or a personnel-protection system and never replaces them. Where possible, connect through the facility's CA gateway with its access-security rules, and limit writes with--option put_allowlist=.
Try it without hardware
The simulator is a real Channel Access server running in-process. It is bound to 127.0.0.1 on random free ports, and the client is pointed only at that address (auto address list off), so it neither broadcasts on nor answers your network. It serves SIM:TEMP (°C, with alarm limits, following SIM:TEMP:SP while SIM:HEATER is On), SIM:MTR (a motor whose put-callback completes only when the move is done, with SIM:MTR:RBV, :DMOV, :STOP and :VELO), SIM:DET:FRAMES, SIM:SAMPLE (string), SIM:SPECTRUM (a 512-point waveform), SIM:BEAM:CURRENT and SIM:STATUS.
Connect to your control system
- Network: your computer must reach the IOCs, or the facility's CA gateway: UDP 5064/5065 and TCP 5064 through any firewall. Most facilities put control networks behind a gateway, so ask your controls group for its address.
- Address list: Channel Access finds PVs by UDP search. Either use your usual EPICS environment (
EPICS_CA_ADDR_LIST,EPICS_CA_AUTO_ADDR_LIST), or pass it explicitly: Passing an address list switches the automatic (broadcast) list off unless you add--option auto_addr_list=yes. With--option check_pv=<a PV you know exists>,--checkreads that PV and prints its value, or the reason it can't be reached. Without it,--checkonly confirms that the CA client starts.
Add to your MCP client
Claude Code (read-only, recommended)
Claude Desktop / Cursor / Windsurf (claude_desktop_config.json, .cursor/mcp.json, …)
Authorised writes (example: a beamline scientist lets the agent move only the sample stage and the filter wheel, and configures an emergency safe state):
Tools
Safety limits
Override at launch, e.g. --limit max_put_batch=4. The main write guards are options, not numeric limits:
Example prompts
- "What is the storage-ring current, and are any of the BL7 vacuum gauges in alarm?"
- "Read BL7:MONO:ENERGY and its readback, and tell me the units and control limits."
- "Monitor the sample temperature for 30 s and tell me whether it is still drifting."
- "Move the sample stage X to 12.5 mm and confirm the readback when the move is done."
- "Record the detector spectrum waveform and tell me where the peak is."
- "Stop everything: apply the safe state."
Notes
- Setpoint versus readback: for motor records,
NAME(VAL) is the target andNAME.RBVis the actual position.put_pvreturns the value read back from the PV you wrote, so read the readback PV separately to confirm physical motion. - Control limits come from the CA
DBR_CTRLresponse. EPICS convention treats equal low and high limits (normally 0/0) as "not configured", and those PVs are only type-checked. - NaN and infinity: JSON has neither. A NaN or infinite scalar value comes back as the text
"nan","inf"or"-inf", array elements asnull, a limit that is NaN (EPICS 3.16+ reports unset alarm limits that way) asnull, and waveform and monitor statistics leave such values out and count them (non_finite,non_finite_updates). - Alarms: every reading includes severity (
NO_ALARM,MINOR_ALARM,MAJOR_ALARM,INVALID_ALARM), status (HIHI,LOLO,UDF,COMM, …) andage_s, the time since the IOC timestamp, so stale values stand out. - Waveforms are downsampled by block averaging to
max_elements, with min/max/mean/argmax statistics. CHAR waveforms are also decoded to text (as_string), the usual EPICS long-string convention. When writing, a text value is accepted for CHAR waveforms. - pvAccess: only Channel Access is supported. caproto 1.x implements CA only, and pvAccess would need p4p, a compiled EPICS Base binding that is deliberately not a dependency. EPICS 7 IOCs serve their records over both CA and PVA, so this covers normal records. PVA-only data (for example NTNDArray images from areaDetector's PVA plugin, or QSRV group PVs) can't be read.
- The CA client is configured through
EPICS_CA_*environment variables, as in EPICS Base. The server sets them for its own process from--address/--optionand restores them on disconnect. Ifput_allowlistholds a comma, pass it on the command line or giveLABMCP_OPTIONSin its JSON form ({"put_allowlist": "BL7:(A|B){1,2}"}), because thea=1,b=2form splits on commas. get_command_logrecords every write (caput -c NAME value) and its read-back.
Hardware verification
Source: servers/protocols/epics/README.md at commit 46545ea
Tools
0Version history
2- v0.1.2LatestSep 27, 2026
- v0.1.0Sep 26, 2026
Score
50% of the applicable checks met
How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.
- Reached in the last 30 days25 pts
Keep the endpoint answering the MCP handshake; SourceWeft probes it every 30 days.
- Auth declared10 pts
Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.
- Tools listed15 pts
Answer tools/list without a credential, or ship a package that starts in a sandbox without one.
- DescriptionRequired15 pts
- Logo10 pts
- Documentation15 pts
- License10 pts
