EPICS Channel Access — Claude Code MCP server: read, monitor
Gives an agent access to EPICS process variables: read them, watch them change, and write when you allow it. Built for accelerator and lab control systems.
claude mcp add --env LABMCP_ADDRESS=<LABMCP_ADDRESS> --env LABMCP_SIMULATE=<LABMCP_SIMULATE> --env LABMCP_READ_ONLY=<LABMCP_READ_ONLY> --env LABMCP_LIMITS=<LABMCP_LIMITS> --transport stdio epics -- uvx labmcp-epicsWhat EPICS Channel Access does
The server talks to EPICS over Channel Access and exposes a set of tools for process variables. Reading covers a lot: get_pv returns a value with units, precision, alarm state and limits, get_pvs fetches a batch at once, and monitor_pv subscribes for a chosen number of seconds and reports statistics. pv_info shows which IOC serves a variable and whether this client holds write access.
Writes live in put_pv and put_pvs and stay off unless you turn them on. A write goes through only when the PV matches the allow-list set with --option put_allowlist=, the IOC grants access, and the value sits inside DRVL/DRVH. Run with --read-only until the responsible scientist authorises otherwise — a write can move motors, open shutters or change magnet setpoints. Even in read-only mode apply_safe_state remains available for the preconfigured emergency state.
No build step is involved: caproto handles CA in pure Python, so libca never enters the picture. Before touching hardware, uvx labmcp-epics --simulate --check starts a real CA server in-process on 127.0.0.1 with random ports and test PVs such as SIM:TEMP and SIM:MTR. A live control network needs UDP 5064 and 5065 plus TCP 5064 open to the IOC or gateway. Point the client with --address or EPICS_CA_ADDR_LIST; supplying a list turns the automatic broadcast search off unless --option auto_addr_list=yes is present.
What it helps with
- read vacuum gauge values on a beamline
- watch beam current and catch trips
- check whether the client may write to a PV
- move a sample stage or filter wheel under authorisation
- drive the setup into a safe state with one call
Example prompts for the agent
- Read
BL7:RING:Iand tell me if it's in alarm. - Monitor
SIM:TEMPfor ten seconds and show the statistics. - Set
BL7:SAMPLE:X.STOPto 1, writes are allowed.
How to install EPICS Channel Access
Platform CLI
claude mcp add --env LABMCP_ADDRESS=<LABMCP_ADDRESS> --env LABMCP_SIMULATE=<LABMCP_SIMULATE> --env LABMCP_READ_ONLY=<LABMCP_READ_ONLY> --env LABMCP_LIMITS=<LABMCP_LIMITS> --transport stdio epics -- uvx labmcp-epicsReplace <…> with your own values. uvx runs the command named after the package; if the README names another one, use uvx --from labmcp-epics <command>
Platform CLI
codex mcp add epics --env LABMCP_ADDRESS=<LABMCP_ADDRESS> --env LABMCP_SIMULATE=<LABMCP_SIMULATE> --env LABMCP_READ_ONLY=<LABMCP_READ_ONLY> --env LABMCP_LIMITS=<LABMCP_LIMITS> -- uvx labmcp-epicsReplace <…> with your own values. uvx runs the command named after the package; if the README names another one, use uvx --from labmcp-epics <command>
Config file
{
"mcpServers": {
"epics": {
"command": "uvx",
"args": [
"labmcp-epics"
],
"env": {
"LABMCP_ADDRESS": "<LABMCP_ADDRESS>",
"LABMCP_SIMULATE": "<LABMCP_SIMULATE>",
"LABMCP_READ_ONLY": "<LABMCP_READ_ONLY>",
"LABMCP_LIMITS": "<LABMCP_LIMITS>"
}
}
}
}Replace <…> with your own values. uvx runs the command named after the package; if the README names another one, use uvx --from labmcp-epics <command>
Config file
{
"servers": {
"epics": {
"type": "stdio",
"command": "uvx",
"args": [
"labmcp-epics"
],
"env": {
"LABMCP_ADDRESS": "<LABMCP_ADDRESS>",
"LABMCP_SIMULATE": "<LABMCP_SIMULATE>",
"LABMCP_READ_ONLY": "<LABMCP_READ_ONLY>",
"LABMCP_LIMITS": "<LABMCP_LIMITS>"
}
}
}
}Replace <…> with your own values. uvx runs the command named after the package; if the README names another one, use uvx --from labmcp-epics <command>
Platform CLI
gemini mcp add -e LABMCP_ADDRESS=<LABMCP_ADDRESS> -e LABMCP_SIMULATE=<LABMCP_SIMULATE> -e LABMCP_READ_ONLY=<LABMCP_READ_ONLY> -e LABMCP_LIMITS=<LABMCP_LIMITS> epics uvx labmcp-epicsReplace <…> with your own values. uvx runs the command named after the package; if the README names another one, use uvx --from labmcp-epics <command>
Step by step, with commands for each platform: How to add an MCP server to Claude Code, Codex, Cursor, VS Code, Gemini CLI and more
Questions about EPICS Channel Access
How do I install EPICS Channel Access in Claude Code?
Run claude mcp add labmcp-epics -- uvx labmcp-epics. To pass address, simulation, read-only and limits, use the env variant: `claude mcp add --env LABMCP_ADDRESS=<LABMCP_ADDRESS> --env LABMCP_SIMULATE=<LABMCP_SIMULATE> --env LABMCP_READ_ONLY=<LABMCP_READ_ONLY> --env LABMCP_LIMITS=<LABMCP_LIMITS> --transport stdio epics -- uvx labmcp-epics`.
What does EPICS Channel Access do?
It lets an agent read EPICS process variables, subscribe to their updates, and write values when the allow-list and IOC access rights permit it.
Can I try it without hardware?
Yes. uvx labmcp-epics --simulate --check runs a CA server in-process on 127.0.0.1 with test PVs, so your network stays untouched.