SecsHost MCP — Unscripted Live Session
Cold agent session against live HSMS loopback equipment: connect, health check, events, alarms, and trace — with raw tool results.
- Session
- Aug 1, 2026, 12:18 AM UTC
- Server
- SecsHost.Mcp (bundled with SecsHost downloads)
- Equipment
- Loopback equipment at 127.0.0.1 (local simulator)
- Operator
- Cursor agent (cold read of tool descriptions via tools/list)
Operator brief
“Connect to the tool, check it is alive, watch for events while I run the sim, tell me what happened.”
Cold session: the agent only saw MCP tool descriptions from tools/list — no prior SecsHost MCP playbook.
Action timeline
- 1
connectTool `connect` matches the brief. Mode active, deviceId 1 (common GEM default), loopback port from sim.
Arguments
{ "ip": "127.0.0.1", "port": 62238, "deviceId": 1, "mode": "active" }Result
{ "ok": true, "status": { "connectionName": "mcp", "isConnected": true, "selectedState": "Selected", "ipAddress": "127.0.0.1", "port": 62238, "deviceId": 1, "mode": "Active", "timerConfig": { "t3ReplyMs": 45000, "t5ConnectSeparationMs": 10000, "t6ControlMs": 5000, "t7NotSelectedMs": 10000, "t8NetworkIntercharacterMs": 5000, "notes": "T3 enforced by HsmsHostConnection.SendMessageAndWaitForReply; T6 partially used for active TCP connect wait; T5/T7/T8 configured on ConnectionSettings but not fully enforced in the engine today." } } } - 2
are_you_there`are_you_there` is the described health check (S1F1/S1F2). Prefer it over raw SML.
Result
{ "ok": true, "replySml": "S1F2\n<L [2]\n <A \"LIVE-SIM\">\n <A \"3.0\">\n>\n.", "mdln": "LIVE-SIM", "softrev": "3.0", "transactionId": 2 } - 3
get_status_variables`get_status_variables` will attempt S1F11 once; loopback ignores S1F11 — expect numeric SVIDs + note.
Arguments
{ "svids": "[1,2]" }Result
{ "ok": true, "replySml": "S1F4\n<L [2]\n <U4 100>\n <U4 101>\n>\n.", "nameResolutionNote": "S1F11/S1F12 name resolution skipped or failed; status variables will use numeric SVIDs. [mcp] T3 reply timeout for S1F11 (TID 3).", "cachedSvidNames": 0, "values": [ { "index": 0, "svid": 1, "value": "U4 100", "valueSml": "<U4 100>" }, { "index": 1, "svid": 2, "value": "U4 101", "valueSml": "<U4 101>" } ] } - 4
get_recent_eventsBrief says watch for events — `get_recent_events` / `get_recent_alarms` fill passively; no subscribe call.
Result
{ "count": 2, "nextSeq": 5, "entries": [ { "seq": 1, "utcTimestamp": "2026-08-01T00:18:13.4764691Z", "kind": "Event", "ceidOrAlid": 2001, "reportDataSummary": "L[1] {L[2] {U4 1 L[1] {A \"ceid-2001\"}}}", "rawSml": "S6F11 W\n<L [3]\n <U4 0>\n <U4 2001>\n <L [1]\n <L [2]\n <U4 1>\n <L [1]\n <A \"ceid-2001\">\n >\n >\n >\n>\n.", "transactionId": 8001 }, { "seq": 2, "utcTimestamp": "2026-08-01T00:18:13.4795595Z", "kind": "Event", "ceidOrAlid": 2002, "reportDataSummary": "L[1] {L[2] {U4 1 L[1] {A \"ceid-2002\"}}}", "rawSml": "S6F11 W\n<L [3]\n <U4 0>\n <U4 2002>\n <L [1]\n <L [2]\n <U4 1>\n <L [1]\n <A \"ceid-2002\">\n >\n >\n >\n>\n.", "transactionId": 8002 } ] } - 5
get_recent_alarmsResult
{ "count": 2, "nextSeq": 5, "entries": [ { "seq": 3, "utcTimestamp": "2026-08-01T00:18:13.5554911Z", "kind": "Alarm", "ceidOrAlid": 77, "alarmSetOrClear": true, "reportDataSummary": "L[3] {B[1] 128 U4 77 A \"LIVE SET\"}", "rawSml": "S5F1 W\n<L [3]\n <B 0x80>\n <U4 77>\n <A \"LIVE SET\">\n>\n.", "transactionId": 8003 }, { "seq": 4, "utcTimestamp": "2026-08-01T00:18:13.6473956Z", "kind": "Alarm", "ceidOrAlid": 77, "alarmSetOrClear": false, "reportDataSummary": "L[3] {B[1] 0 U4 77 A \"LIVE CLEAR\"}", "rawSml": "S5F1 W\n<L [3]\n <B 0x00>\n <U4 77>\n <A \"LIVE CLEAR\">\n>\n.", "transactionId": 8004 } ] } - 6
get_recent_eventsIncremental poll with `sinceSeq=2` — expect only events at/after that seq (second rapid-fire CEID).
Arguments
{ "sinceSeq": 2 }Result
{ "count": 1, "nextSeq": 5, "entries": [ { "seq": 2, "utcTimestamp": "2026-08-01T00:18:13.4795595Z", "kind": "Event", "ceidOrAlid": 2002, "reportDataSummary": "L[1] {L[2] {U4 1 L[1] {A \"ceid-2002\"}}}", "rawSml": "S6F11 W\n<L [3]\n <U4 0>\n <U4 2002>\n <L [1]\n <L [2]\n <U4 1>\n <L [1]\n <A \"ceid-2002\">\n >\n >\n >\n>\n.", "transactionId": 8002 } ] } - 7
get_trace`get_trace` for receipts including ConnectionHandler acks (S6F12/S5F2), not Select frames.
Result
{ "count": 13, "nextSeq": 14, "entries": [ { "seq": 1, "utcTimestamp": "2026-08-01T00:18:13.4892019Z", "rawTimestamp": "2026-08-01T00:18:13.4892019Z", "direction": "Tx", "sxFy": "S1F1", "sml": "S1F1 /* bus */ S1F1 ()", "systemBytes": 2, "rawPayload": "S1F1 ()|TID:2" }, { "seq": 2, "utcTimestamp": "2026-08-01T00:18:13.477Z", "rawTimestamp": "20:18:13.477", "direction": "Rx", "sxFy": "S6F11", "sml": "S6F11 /* bus */ S6F11 (L {U4 0} {U4 2001} L L {U4 1} L {A ceid-2001})", "systemBytes": 8001, "rawPayload": "S6F11 (L {U4 0} {U4 2001} L L {U4 1} L {A ceid-2001})|TID:8001" }, { "seq": 3, "utcTimestamp": "2026-08-01T00:18:13.48Z", "rawTimestamp": "20:18:13.480", "direction": "Rx", "sxFy": "S6F11", "sml": "S6F11 /* bus */ S6F11 (L {U4 0} {U4 2002} L L {U4 1} L {A ceid-2002})", "systemBytes": 8002, "rawPayload": "S6F11 (L {U4 0} {U4 2002} L L {U4 1} L {A ceid-2002})|TID:8002" }, { "seq": 4, "utcTimestamp": "2026-08-01T00:18:13.5036301Z", "rawTimestamp": "2026-08-01T00:18:13.5036301Z", "direction": "Rx", "sxFy": "S1F2", "sml": "S1F2 /* bus */ S1F2 (L[2] {A \"LIVE-SIM\" A \"3.0\"})", "systemBytes": 2, "rawPayload": "S1F2 (L[2] {A \"LIVE-SIM\" A \"3.0\"})|TID:2" }, { "seq": 5, "utcTimestamp": "2026-08-01T00:18:13.510507Z", "rawTimestamp": "2026-08-01T00:18:13.5105070Z", "direction": "Tx", "sxFy": "S1F11", "sml": "S1F11 /* bus */ S1F11 (L[0] {})", "systemBytes": 3, "rawPayload": "S1F11 (L[0] {})|TID:3" }, { "seq": 6, "utcTimestamp": "2026-08-01T00:18:13.539Z", "rawTimestamp": "20:18:13.539", "direction": "Tx", "sxFy": "S6F12", "sml": "S6F12 /* bus */ S6F12 (<BIN>0</BIN>)", "systemBytes": 8002, "rawPayload": "S6F12 (<BIN>0</BIN>)|TID:8002" }, { "seq": 7, "utcTimestamp": "2026-08-01T00:18:13.539Z", "rawTimestamp": "20:18:13.539", "direction": "Tx", "sxFy": "S6F12", "sml": "S6F12 /* bus */ S6F12 (<BIN>0</BIN>)", "systemBytes": 8001, "rawPayload": "S6F12 (<BIN>0</BIN>)|TID:8001" }, { "seq": 8, "utcTimestamp": "2026-08-01T00:18:13.555Z", "rawTimestamp": "20:18:13.555", "direction": "Rx", "sxFy": "S5F1", "sml": "S5F1 /* bus */ S5F1 (L {Bi System.Byte[]} {U4 77} {A LIVE SET})", "systemBytes": 8003, "rawPayload": "S5F1 (L {Bi System.Byte[]} {U4 77} {A LIVE SET})|TID:8003" }, { "seq": 9, "utcTimestamp": "2026-08-01T00:18:13.615Z", "rawTimestamp": "20:18:13.615", "direction": "Tx", "sxFy": "S5F2", "sml": "S5F2 /* bus */ S5F2 (<BIN>0</BIN>)", "systemBytes": 8003, "rawPayload": "S5F2 (<BIN>0</BIN>)|TID:8003" }, { "seq": 10, "utcTimestamp": "2026-08-01T00:18:13.647Z", "rawTimestamp": "20:18:13.647", "direction": "Rx", "sxFy": "S5F1", "sml": "S5F1 /* bus */ S5F1 (L {Bi System.Byte[]} {U4 77} {A LIVE CLEAR})", "systemBytes": 8004, "rawPayload": "S5F1 (L {Bi System.Byte[]} {U4 77} {A LIVE CLEAR})|TID:8004" }, { "seq": 11, "utcTimestamp": "2026-08-01T00:18:13.708Z", "rawTimestamp": "20:18:13.708", "direction": "Tx", "sxFy": "S5F2", "sml": "S5F2 /* bus */ S5F2 (<BIN>0</BIN>)", "systemBytes": 8004, "rawPayload": "S5F2 (<BIN>0</BIN>)|TID:8004" }, { "seq": 12, "utcTimestamp": "2026-08-01T00:18:58.5336041Z", "rawTimestamp": "2026-08-01T00:18:58.5336041Z", "direction": "Tx", "sxFy": "S1F3", "sml": "S1F3 /* bus */ S1F3 (L[2] {U4 1 U4 2})", "systemBytes": 4, "rawPayload": "S1F3 (L[2] {U4 1 U4 2})|TID:4" }, { "seq": 13, "utcTimestamp": "2026-08-01T00:18:58.5368722Z", "rawTimestamp": "2026-08-01T00:18:58.5368722Z", "direction": "Rx", "sxFy": "S1F4", "sml": "S1F4 /* bus */ S1F4 (L[2] {U4 100 U4 101})", "systemBytes": 4, "rawPayload": "S1F4 (L[2] {U4 100 U4 101})|TID:4" } ] } - 8
get_connection_statusResult
{ "connectionName": "mcp", "isConnected": true, "selectedState": "Selected", "ipAddress": "127.0.0.1", "port": 62238, "deviceId": 1, "mode": "Active", "timerConfig": { "t3ReplyMs": 45000, "t5ConnectSeparationMs": 10000, "t6ControlMs": 5000, "t7NotSelectedMs": 10000, "t8NetworkIntercharacterMs": 5000, "notes": "T3 enforced by HsmsHostConnection.SendMessageAndWaitForReply; T6 partially used for active TCP connect wait; T5/T7/T8 configured on ConnectionSettings but not fully enforced in the engine today." } } - 9
disconnectResult
{ "ok": false, "status": { "connectionName": "mcp", "isConnected": false, "selectedState": "NotSelected", "ipAddress": "127.0.0.1", "port": 62238, "deviceId": 1, "mode": "Active", "timerConfig": { "t3ReplyMs": 45000, "t5ConnectSeparationMs": 10000, "t6ControlMs": 5000, "t7NotSelectedMs": 10000, "t8NetworkIntercharacterMs": 5000, "notes": "T3 enforced by HsmsHostConnection.SendMessageAndWaitForReply; T6 partially used for active TCP connect wait; T5/T7/T8 configured on ConnectionSettings but not fully enforced in the engine today." } } }
Agent summary
- Connected active HSMS to loopback; SELECTED.
- Are-You-There returned equipment identity from S1F2.
- Status variables: S1F11 ignored by sim → graceful numeric SVIDs (see nameResolutionNote).
- Two rapid S6F11 events (CEID 2001 then 2002) observed with monotonic seq; sinceSeq filtered correctly.
- Alarm ALID 77 set then clear observed with alarmSetOrClear true/false.
- Trace shows Rx reports + Tx ConnectionHandler acks; no HSMS control frames.
Verdict: tool descriptions were sufficient to operate without clarifying questions.
Tool descriptions the agent saw (9)Expand
are_you_thereSend S1F1 (Are You There) and wait for S1F2. Returns MDLN and SOFTREV when the equipment supplies the common L[2] {A MDLN, A SOFTREV} body. Use this as a quick comms health check after connect. Requires an HSMS-SELECTED session.
connectOpen the single HSMS-SS session owned by this MCP server. Active mode dials ip:port and sends Select.req (typical host→equipment). Passive mode listens on ip:port for an incoming Select (equipment-side). deviceId is the HSMS session/device id in data-message headers (often 0 or 1). On success the link is SELECTED; on Select timeout the error explains common causes (wrong role, device id, or peer already bound). Replaces any prior MCP connection.
disconnectGracefully disconnect the MCP HSMS session (best-effort Separate.req then close). Returns the final connection status. Safe to call when already disconnected.
get_connection_statusReturn the current HSMS connection status for this SecsHost MCP session: Selected/NotSelected, remote endpoint (ip/port), deviceId, active/passive mode, and the SEMI E37 timer budgets (T3/T5/T6/T7/T8) as configured by SecsService.Connect. Call this after connect/disconnect or when diagnosing timeouts.
get_recent_alarmsReturn recent alarms (S5F1) from the typed EventBuffer. Buffers fill passively while connected — ConnectionHandler auto-acks with S5F2; MCP does not send acks. alarmSetOrClear is true when ALCD bit 7 indicates set, false for clear. rawSml is round-trippable SML. Optional sinceSeq for incremental polling.
get_recent_eventsReturn recent collection events (S6F11) from the typed EventBuffer. Buffers fill passively while connected — ConnectionHandler auto-acks with S6F12; MCP does not send acks and no subscription call is required. Each entry includes seq (for incremental polling via sinceSeq), ceidOrAlid (CEID), reportDataSummary, and rawSml — round-trippable SML suitable for send_secs_message-style replay. Optional sinceSeq returns only entries with seq >= sinceSeq.
get_status_variablesQuery status variables via S1F3/S1F4. Optional svids is a JSON array of numeric SVIDs (e.g. [1001,1002]); omit or pass [] to request the equipment's default/empty list. Once per session this tool attempts S1F11/S1F12 name resolution and caches the map; if the equipment ignores S1F11, values are returned with numeric SVIDs and a note. Requires an HSMS-SELECTED session.
get_traceReturn the decoded SECS traffic log (ring buffer, default capacity 2000). Each entry has seq, utcTimestamp, direction (Tx=host→equipment, Rx=equipment→host), sxfy, sml-ish body, and systemBytes when known. Optional count limits how many recent entries to return; optional sinceSeq returns entries with seq >= sinceSeq. NOTE: HSMS control messages (Select/Linktest/Separate) do NOT appear here — ISecsTrafficBus only carries SECS-II data MessageSent events.
send_secs_messageSend any SxFy as standard SML and optionally wait for the secondary reply. This is the universal escape hatch when a typed GEM tool does not exist yet. SML grammar: 'S' stream 'F' function optional 'W' (reply expected), optional body items like <L [n] ...>, <A "text">, <U4 1>, <BOOLEAN TRUE>, then terminating '.'. Example (Are You There): S1F1 W. On success returns replySml (formatted via SmlFormatter). On T3 timeout returns structured diagnosis: which timer, connection state, lastTraceSeq. Malformed SML returns a parse error that names the offending token and character position.