
ASTM LIS Analyzer Receiver
io.github.K-Dense-AIPublished by GitHub account K-Dense-AIv0.1.3Updated Oct 24, 2026
MCP server that receives results from clinical/lab analyzers over ASTM E1381/E1394 (CLSI LIS1/LIS2).
Overview
Receive-only MCP server that collects ASTM E1381/E1394 results from clinical lab analyzers and lets an assistant query them by sample, patient, test or time.
- What you can do
- Query received results filtered by sample ID, patient ID, test code, time received or abnormal flag, and open one result's full decoded fields, comments and raw records. List recent ASTM messages and inspect the analyzer link state, message counts and link-layer error counters. Check connection identity, address, read-only mode and active limits, and review the raw command log for debugging. Reconnect the link after a power cycle or cable change, and clear stored results between runs.
- When to use it
- For laboratory operations and research work where an analyzer uploads results over an ASTM host interface and you want an assistant to look up, filter or summarize what arrived. Not for reporting, releasing or interpreting patient results, diagnosis or any clinical decision-making.
- Requirements
- Runs locally as a Python package (uvx labmcp-astm-lis) over stdio; desktop only. Needs a link to the analyzer: a serial device path, or a TCP address or listen port, set via LABMCP_ADDRESS or command-line options. The analyzer must have ASTM E1381 framing and automatic result upload enabled, with host query and order modes turned off. LABMCP_SIMULATE=1 runs a built-in simulator without hardware.
Installation
In SourceWeft
- Open ASTM LIS Analyzer Receiver 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
ASTM LIS Analyzer Receiver — MCP Server
Let an AI agent collect and query results from clinical and laboratory analyzers (hematology, clinical chemistry, immunoassay, urinalysis, coagulation) that upload results over the standard ASTM E1381 / E1394 host interface (CLSI LIS1-A / LIS2-A2). The server acts as a small, receive-only LIS endpoint: it acknowledges the analyzer's frames, validates checksums, reassembles messages and lets the agent look results up by sample, patient, test or time.
[!WARNING] Research and lab-operations use only. This is not a medical device and not a validated laboratory information system. It must not be used to report, release or interpret patient results, for diagnosis, or for any clinical decision-making. Results pass through an AI agent that can misread them; always rely on your laboratory's validated LIS/middleware and release process. Patient data is personal health information: patient name, birth date, address and phone are redacted by default; follow your institution's privacy rules before changing that.
Try it without hardware
The simulated analyzer uploads two messages right after start: a CBC with 5-part differential (with H/L flags and suspect-flag comments, one record long enough to need two frames, and one frame corrupted on the line that is NAKed and retransmitted) and a chemistry panel (high glucose and potassium with a hemolysis comment). All patient data in it is fictitious.
Connect your analyzer
On the analyzer, open the host / LIS / "online" communication settings:
- Protocol: ASTM (may be called ASTM E1381/E1394, LIS1-A/LIS2-A2, CLSI or "ASTM host"). Keep the ASTM low-level protocol (ENQ/STX framing) enabled, also over TCP/IP.
- Results: enable automatic result upload.
- Queries and orders: this server does not answer host queries or download orders. Turn off "host query" / "order request" / bidirectional mode, otherwise the analyzer waits for (and times out on) an answer before running samples.
- Link: pick one of
- RS-232: note the baud rate (commonly 9600), 8 data bits, no parity, 1 stop bit (fixed by E1381), and use a null-modem cable.
- TCP, analyzer is the server (it listens on a port): the LIS connects to it.
- TCP, analyzer is the client (you enter the host IP/port on the analyzer): this server listens. Allow the port through the computer's firewall and restrict senders with
allow_from.
- Optional: keep a local record of every message with
--option store_path=~/lis/results.jsonl(the newestmax_messagesare reloaded when the server restarts; if the file cannot be written, messages are still kept in memory andget_connection_statusreportsstore_write_errors).
The receiver starts as soon as the MCP server starts, so uploads are acknowledged even before the agent calls a tool. Received results stay in memory across reconnect (only clear_results or a server restart without store_path removes them), because the analyzer never re-sends a result it has been sent an ACK for.
Add to your MCP client
Claude Code
Claude Desktop / Cursor / Windsurf (claude_desktop_config.json, .cursor/mcp.json, …)
Add --read-only to hide clear_results. For other clients, generate the snippet with uvx labmcp config astm-lis --address /dev/ttyUSB0 --client vscode (also cursor, codex, claude-code).
Tools
get_connection_info, get_command_log and reconnect are built into every LabMCP server.
Safety limits
This server is receive-only and never commands the analyzer (it only answers ACK/NAK), so it has no physical safety limits. Privacy settings:
Patient IDs, sex, attending physician and free-text comment records are not redacted (IDs are needed to filter results). If your analyzers put identifying text in comments, treat the output accordingly.
Example prompts
- "Have any results come in from the hematology analyzer in the last hour? List the samples."
- "Show me all flagged results for sample S26-000123, with units, reference ranges and the analyzer's comments."
- "Export today's potassium results as a table of sample ID, value and flag."
- "Is the analyzer link healthy? How many frames were NAKed today and why?"
- "Compare the glucose results of samples S26-000124 and S26-000131."
- "Clear the stored results before we start the next validation run."
Notes
- Receive-only. No order download, no host-query responses and no result acknowledgements beyond the link-level ACK. Query (Q) messages from the analyzer are stored and reported (
kind: "query") but not answered. Order download is planned future work. - Link layer (E1381). Every frame is checked: checksum (modulo-256 sum from the frame number to ETX/ETB, as two hex digits), frame number (first frame 1, then modulo 8; a repeat of the last accepted number is treated as a retransmission and ACKed without duplicating data) and framing. Defective frames get NAK and the analyzer retransmits them. Frames outside an ENQ … EOT session are ignored and counted in
bytes_ignored, which usually means the analyzer is not using the ASTM low-level protocol (raw E1394 without framing is not supported). A session that goes silent for 30 s, or restarts with ENQ, has its incomplete message discarded, as E1381 requires; a message that ends with EOT but no terminator (L) record is kept and flaggedcomplete: false. - Tolerances. Frames with more than 240 text characters and end frames that pack several records are accepted (and counted); a frame whose CR LF never arrives is NAKed after 10 s. Text is decoded as Latin-1 by default (
--option encoding=...; an unknown encoding name is refused at start-up). - Records (E1394). Delimiters are taken from each header record (
H|\^&by default). Escape sequences&F& &S& &R& &E&and the vendor form&|&are decoded; other escapes are kept verbatim. The test code is the first non-empty "local code" component of the Universal Test ID (^^^TSH,^^^^WBC), falling back to the first component. The sample ID is the order's Specimen ID, or the first non-empty component of the Instrument Specimen ID. Values are returned exactly as sent ("<0.1",">500","Cancelled");numeric_valueis only set for plain numbers. - Flags and statuses are passed through as sent. Meanings are only attached for the abnormal flags defined by LIS2-A2 / E1394 (
N L H LL HH < > A U D B W) and the result statuses documented in the vendor specification used (F X); anything else is analyzer-specific, so check your analyzer's host-interface manual. - Timestamps inside records (test started/completed, header time) are the analyzer's local time;
received_atis when this server stored the message (UTC). - Listen mode serves one analyzer per port: a new connection replaces the previous one (analyzers often reconnect after a reboot without closing the old socket). Run one server entry (or port) per analyzer. There is no TLS; keep the port on the lab network and use
allow_from. - Only tested against the simulator and loopback TCP. Differences between vendors' ASTM dialects are common; please report what works (or doesn't) with your analyzer.
Hardware verification
Source: servers/health/astm-lis-analyzer/README.md at commit 46545ea
Tools
0Version history
2- v0.1.3LatestSep 27, 2026
- v0.1.1Sep 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