Spec Driven Development
MCP Server that facilitates spec-driven development workflows, not just Vibe Coding.
제작자가 쓴 설명(영어 원문)
MCP server for EPICS Channel Access: read, monitor and guarded writes of process variables.
이 세 가지는 절대 하나의 점수로 합치지 않아요. 의견, 측정, 인기는 서로 다른 것이니까요.
이 서버는 아직 쉬운 말로 된 요약을 쓰지 못했어요. 아래는 레지스트리에서 읽어 온 사실이에요.
쓰고 있는 AI 앱을 고른 다음 설정을 복사하세요.
LABMCP_ADDRESS, LABMCP_SIMULATE, LABMCP_READ_ONLY, LABMCP_LIMITS필요한 것
어떤 앱을 쓰세요?
위에서 앱을 고르세요. 기억해 두었다가 다음부터는 버튼에 “…에 설치”라고 표시해요.
Claude Desktop → Settings → Developer → Edit Config를 열고 claude_desktop_config.json에 이 내용을 붙여 넣으세요
{
"mcpServers": {
"labmcp-epics": {
"command": "uvx",
"args": [
"labmcp-epics"
],
"env": {
"LABMCP_ADDRESS": "your-value",
"LABMCP_SIMULATE": "your-value",
"LABMCP_READ_ONLY": "your-value",
"LABMCP_LIMITS": "your-value"
}
}
}
}터미널에서 이 명령어를 실행하세요
claude mcp add labmcp-epics --env LABMCP_ADDRESS=your-value --env LABMCP_SIMULATE=your-value --env LABMCP_READ_ONLY=your-value --env LABMCP_LIMITS=your-value -- uvx labmcp-epics실행하기 전에 빈 값을 채워 주세요.
프로젝트의 .cursor/mcp.json 또는 ~/.cursor/mcp.json에 붙여 넣으세요
{
"mcpServers": {
"labmcp-epics": {
"command": "uvx",
"args": [
"labmcp-epics"
],
"env": {
"LABMCP_ADDRESS": "your-value",
"LABMCP_SIMULATE": "your-value",
"LABMCP_READ_ONLY": "your-value",
"LABMCP_LIMITS": "your-value"
}
}
}
}브라우저가 앱을 열지 물어본 다음, 앱이 설정을 보여 주고 확인을 요청해요. 키 값은 비워 두니 직접 입력하세요.
프로젝트의 .vscode/mcp.json에 붙여 넣으세요
{
"servers": {
"labmcp-epics": {
"type": "stdio",
"command": "uvx",
"args": [
"labmcp-epics"
],
"env": {
"LABMCP_ADDRESS": "your-value",
"LABMCP_SIMULATE": "your-value",
"LABMCP_READ_ONLY": "your-value",
"LABMCP_LIMITS": "your-value"
}
}
}
}브라우저가 앱을 열지 물어본 다음, 앱이 설정을 보여 주고 확인을 요청해요. 키 값은 비워 두니 직접 입력하세요.
이 서버는 내 컴퓨터에서 실행되는데, ChatGPT는 인터넷에 있는 서버에만 연결할 수 있어요. 다른 앱을 고르세요.
선택한 앱은 이 기기의 쿠키에만 저장돼요. 계정은 필요 없어요.
LABMCP_ADDRESS envLABMCP_SIMULATE envLABMCP_READ_ONLY envLABMCP_LIMITS env이 설정은 제작자의 레지스트리 정보로 만들었어요. README와 다르면 README를 따르세요.
내 컴퓨터에서 실행돼요. 설치하면 AI 앱에 도구 목록이 나타나요.
누구나 볼 수 있는 정보를 점검했고, 코드는 읽지 않았어요. 해당하지 않는 항목은 개수에서 뺐어요. · 2026년 11월 8일 점검
레지스트리 이름이 GitHub 계정 K-Dense-AI 기준으로 확인되었고, 이 계정이 저장소를 소유하고 있어요
아직 GitHub에서 이 저장소를 읽어 오지 않았어요
아직 GitHub에서 이 저장소를 읽어 오지 않았어요
내 컴퓨터에서 실행되는 서버라 인터넷 엔드포인트가 없어요
내 컴퓨터에서 실행되며, 대신 로컬 설정을 사용해요
내 컴퓨터에서 실행돼요. 도구 목록은 인터넷 엔드포인트가 있는 서버에서만 읽을 수 있어요
레지스트리에서 이 카테고리의 활성 서버 전체와 비교했어요. 스타는 게시자가 저장소를 소유한 경우에만 세요.
해당하는 기본 점검 1개 중 1개를 통과했어요. 코드는 읽지 않았어요. 키나 토큰을 넣기 전에 서버가 어떤 권한을 요구하는지 확인하고, 꼭 필요한 권한만 있는 키를 쓰세요.
레지스트리에 필수 키가 나와 있지 않아요. 다만 처음 쓸 때 로그인을 요구하는 서버도 있어요.
내 컴퓨터에서 실행돼요. AI 앱이 필요할 때 실행하고, 데이터는 제작자의 서버를 거치지 않아요(서버 자체가 온라인 서비스를 호출하는 경우는 제외).
GitHub 저장소는 마지막으로 – 변경됐고, 최신 버전(0.1.2)은 42일 전 레지스트리에 올라왔어요.
Claude Desktop, Claude Code, Cursor, VS Code처럼 MCP를 지원하는 앱에서 쓸 수 있어요. 내 컴퓨터에 Python (uv)도 있어야 해요.
같은 카테고리에는: Spec Driven Development, Remote Desktop Commander, Tethered Trust
같은 카테고리에서 다른 제작자가 만든 서버예요. 스타 순으로 정렬했어요.
카드 보는 법:★ GitHub 스타i세 기둥: 리뷰 · 점검 · 사용 정도i업데이트 = 최신 버전을 레지스트리에 공개한 날i
MCP Server that facilitates spec-driven development workflows, not just Vibe Coding.
Remote Desktop Commander: use files, terminal and processes on your own computers from any AI app.
Fit, compatibility and recall checks for AI agents before they buy: verdicts, evidence, receipts.
제작자의 저장소에서 쓰인 그대로 가져왔어요. PopNx MCP가 검토하거나 보증한 내용이 아니에요. HTML, 이미지, 스크립트는 제거했어요. 링크를 누르면 이 사이트를 벗어나요.
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-only` unless 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=.
| Package | labmcp-epics |
| Instruments | Any EPICS IOC serving Channel Access: EPICS Base 3.14–7.x soft/hard IOCs, areaDetector, motor, asyn, StreamDevice, caproto/pythonSoftIOC IOCs, CA gateways |
| Interfaces | Ethernet: CA search on UDP 5064, circuits on TCP 5064, repeater on UDP 5065 |
| Protocol | EPICS Channel Access v4.13 (protocol specification, ao record: DRVH/DRVL, caproto threading client) |
| Status | 🧪 simulated: tested against an in-process caproto IOC (real CA over localhost), not yet verified at a facility. Report a hardware test |
uvx labmcp-epics --simulate --check
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.
EPICS_CA_ADDR_LIST, EPICS_CA_AUTO_ADDR_LIST), or pass it explicitly: uvx labmcp-epics --read-only --address 10.0.1.20 --option check_pv=SR:CURRENT --check # one IOC / gateway
uvx labmcp-epics --read-only --option ca_addr_list="gw1.facility.org 10.0.1.21:5064" --option check_pv=BL7:RING:I --check uvx labmcp-epics --read-only --option check_pv=BL7:RING:I --check # use the environment as-is
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>`, `--check` reads that PV and prints its value, or the reason it can't be reached. Without it, `--check` only confirms that the CA client starts.
Claude Code (read-only, recommended)
claude mcp add epics -- uvx labmcp-epics --read-only --address gw1.facility.org
Claude Desktop / Cursor / Windsurf (claude_desktop_config.json, .cursor/mcp.json, …)
{
"mcpServers": { "epics": { "command": "uvx", "args": ["labmcp-epics", "--read-only", "--address", "gw1.facility.org"] } } }
Authorised writes (example: a beamline scientist lets the agent move only the sample stage and the filter wheel, and configures an emergency safe state):
uvx labmcp-epics --address 10.0.7.10 \
--option put_allowlist='BL7:(SAMPLE:(X|Y)|FILTER:POS)' \ --option require_ctrl_limits=true \ --option safe_state='BL7:SAMPLE:X.STOP=1;BL7:SAMPLE:Y.STOP=1;BL7:SHUTTER:CMD=Close'
| Tool | Kind | Description |
|---|---|---|
apply_safe_state | 🛑 safety | Emergency action: write the scientist-configured safe-state PVs (--option safe_state, e.g. motor STOP fields, shutter close, HV off), all of them even if one fails. Available in read-only mode. It does not replace the facility's own interlocks and stop buttons. |
get_command_log | 👁 read | Return the most recent raw commands sent to / replies received from the instrument (newest last). Useful for debugging and for recording what was done. |
get_connection_info | 👁 read | Report which instrument is connected (identity, address, simulated or real), whether the server is read-only, and the active safety limits. Call this first. |
get_pv | 👁 read | Read one PV with its metadata: value, units, precision, alarm severity/status, IOC timestamp and age, display/alarm/warning/control limits and enum state names. Waveforms come back downsampled with min/max/mean statistics. |
get_pvs | 👁 read | Read many PVs at once (e.g. all motors or vacuum gauges of a beamline). PVs that cannot be reached are listed in errors instead of failing the whole call. |
monitor_pv | 👁 read | Subscribe to a PV and collect every value change for duration_s seconds (or until max_updates), then return statistics (min/max/mean/std, drift rate) and the updates. |
put_pv | ⚠️ hazard | Write a PV. This can move motors, open shutters, change magnet or high-voltage setpoints and heat or cool samples: tell the user exactly what will change first. The write is refused unless the PV matches the put allow-list, the IOC grants write access, and the value has the right type and lies within the PV's control limits (DRVL/DRVH). Returns the read-back value. |
put_pvs | ⚠️ hazard | Write several PVs in order (e.g. set both slit blades). Every write is validated first (allow- list, access rights, type, control limits); if any is invalid nothing is written. Writing stops at the first failure and the rest are reported as not written. The whole batch must finish within an hour: writes that would start later are not sent. |
pv_info | 👁 read | Connection details of a PV: serving IOC host:port, native type, element count, and whether this client has read/write access (EPICS access security) and passes the put allow-list. |
reconnect | 🛑 safety | Close and re-open the connection to the instrument (e.g. after it was power cycled or a cable was re-plugged). |
| Limit | Default | Meaning |
|---|---|---|
max_monitor_duration_s | 60 s | Longest monitor_pv collection |
max_put_batch | 10 PVs | Most PVs one put_pvs call may write |
max_put_wait_s | 60 s | Longest wait for one put-callback (completion) |
Override at launch, e.g. --limit max_put_batch=4. The main write guards are options, not numeric limits:
| Guard | How |
|---|---|
| Read-only mode | --read-only hides put_pv and put_pvs entirely |
| Allow-list | --option put_allowlist= : a PV name must fully match it to be written. Prefer patterns that exclude record fields (BL7:SAMPLE:[^.]* rather than BL7:SAMPLE:.*) |
| Limit fields | writes to the fields that set the limits (.DRVH, .DRVL, .HOPR, .LOPR, and the motor record's .HLM, .LLM, .DHLM, .DLLM) are refused, so a write can't raise a limit and then pass it. --option allow_limit_field_writes=true permits them |
| EPICS access security | writes are refused up front if the IOC or gateway grants this client read-only access |
| Control limits | numeric writes outside the PV's control limits are refused. For output records these are DRVL/DRVH, which the IOC would otherwise silently clip to. A NaN limit means no limit on that side |
| No limits configured | allowed with a warning, or refused with --option require_ctrl_limits=true |
| Type checks | enum states must be valid names or indices, integers must be integral and in range, 32-bit FLOAT values must fit, strings are at most 39 latin-1 characters, arrays must fit the element count |
| PV names | no whitespace or quotes, and record names of at most 59 characters (EPICS 3.14+); anything else is refused before a search is sent |
| Batches | put_pvs validates every write before sending any, stops at the first failure, and sends no write once its one-hour budget (inside the tool timeout) is used up |
| Put-completion | put_pv waits for the IOC's put-callback. On timeout it says the IOC may still be processing and not to repeat blindly |
| Safe state | apply_safe_state (SAFETY, available even in read-only mode) writes only the PVs the scientist configured with --option safe_state |
NAME (VAL) is the target and NAME.RBV is the actual position. put_pv returns the value read back from the PV you wrote, so read the readback PV separately to confirm physical motion.DBR_CTRL response. EPICS convention treats equal low and high limits (normally 0/0) as "not configured", and those PVs are only type-checked."nan", "inf" or "-inf", array elements as null, a limit that is NaN (EPICS 3.16+ reports unset alarm limits that way) as null, and waveform and monitor statistics leave such values out and count them (non_finite, non_finite_updates).NO_ALARM, MINOR_ALARM, MAJOR_ALARM, INVALID_ALARM), status (HIHI, LOLO, UDF, COMM, …) and age_s, the time since the IOC timestamp, so stale values stand out.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.EPICS_CA_* environment variables, as in EPICS Base. The server sets them for its own process from --address/--option and restores them on disconnect. If put_allowlist holds a comma, pass it on the command line or give LABMCP_OPTIONS in its JSON form ({"put_allowlist": "BL7:(A|B){1,2}"}), because the a=1,b=2 form splits on commas.get_command_log records every write (caput -c NAME value) and its read-back.앞부분만 보여 드려요. 나머지는 저장소에서 읽어 보세요