<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Didenco Vasile</title>
    <description>The latest articles on DEV Community by Didenco Vasile (@vasiledidencodotcom).</description>
    <link>https://dev.to/vasiledidencodotcom</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3818589%2F7e2b1699-181e-4df2-b7bd-3e2e6db63a88.jpeg</url>
      <title>DEV Community: Didenco Vasile</title>
      <link>https://dev.to/vasiledidencodotcom</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vasiledidencodotcom"/>
    <language>en</language>
    <item>
      <title>How to connect lab instruments to AI using a single protocol (MCP)</title>
      <dc:creator>Didenco Vasile</dc:creator>
      <pubDate>Tue, 24 Mar 2026 10:49:20 +0000</pubDate>
      <link>https://dev.to/vasiledidencodotcom/how-to-connect-lab-instruments-to-ai-using-a-single-protocol-mcp-4oi</link>
      <guid>https://dev.to/vasiledidencodotcom/how-to-connect-lab-instruments-to-ai-using-a-single-protocol-mcp-4oi</guid>
      <description>&lt;p&gt;Most lab instruments still need custom adapters to talk to AI. One per vendor, one per model, one per software version. MCP changes that - one protocol, universal connectivity, schema-validated commands that never reach hardware unless they are valid. We wrote the practical guide: &lt;a href="https://qpillars.com/blog/connect-ai-agents-lab-instruments-mcp" rel="noopener noreferrer"&gt;https://qpillars.com/blog/connect-ai-agents-lab-instruments-mcp&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz22skp17il6v3ymq9aia.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz22skp17il6v3ymq9aia.jpeg" alt=" " width="782" height="455"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Building MCP Servers for Scientific Instruments</title>
      <dc:creator>Didenco Vasile</dc:creator>
      <pubDate>Thu, 12 Mar 2026 12:30:18 +0000</pubDate>
      <link>https://dev.to/qpillars/building-mcp-servers-for-scientific-instruments-4jh9</link>
      <guid>https://dev.to/qpillars/building-mcp-servers-for-scientific-instruments-4jh9</guid>
      <description>&lt;p&gt;Laboratory instruments are some of the most sophisticated hardware on the planet. A modern liquid handler can dispense volumes down to nanoliters with sub-percent precision. A mass spectrometer can identify molecules in a mixture at parts-per-billion concentrations. Yet the software controlling these instruments often looks like it was designed in 2005 - because it was.&lt;/p&gt;

&lt;p&gt;Meanwhile, AI agents are connecting to databases, APIs, and cloud services through increasingly standardized protocols. The Model Context Protocol (MCP) - originally released by Anthropic for connecting AI assistants to tools - is rapidly becoming the standard for agent-to-tool integration.&lt;/p&gt;

&lt;p&gt;We asked a simple question: what if we connected AI agents to physical lab instruments the same way?&lt;/p&gt;

&lt;p&gt;This article explains how we did it, what we learned, and why it matters for the future of laboratory automation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lab Instrument Software Is Stuck
&lt;/h2&gt;

&lt;p&gt;If you work in a lab, you know the pain. Every instrument ships with its own desktop application. These applications rarely talk to each other. Integrating two instruments into a single workflow means one of three things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Manual copy-paste&lt;/strong&gt; - a scientist exports data from instrument A, opens instrument B's software, and manually enters parameters. Error-prone and slow.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vendor-specific SDK&lt;/strong&gt; - if the manufacturer provides one. Typically a COM interface, a .NET DLL, or a REST API documented in a 200-page PDF. Each vendor's approach is different.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Middleware platforms&lt;/strong&gt; - commercial lab automation middleware that costs six figures annually and still requires custom scripting for each instrument.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;None of these approaches scale. And none of them are accessible to the scientists who actually run the experiments.&lt;/p&gt;

&lt;p&gt;The underlying problem is interoperability. Lab instruments speak dozens of different protocols - SiLA2, OPC-UA, SCPI, proprietary serial commands, HTTP APIs - and there is no universal adapter.&lt;/p&gt;

&lt;h2&gt;
  
  
  What MCP Brings to the Table
&lt;/h2&gt;

&lt;p&gt;The Model Context Protocol (MCP) is an open standard for connecting AI models to external tools. It defines a simple contract: a server exposes &lt;strong&gt;tools&lt;/strong&gt; (callable functions), &lt;strong&gt;resources&lt;/strong&gt; (readable data), and &lt;strong&gt;prompts&lt;/strong&gt; (reusable templates). A client - typically an AI agent - discovers these capabilities and uses them to accomplish tasks.&lt;/p&gt;

&lt;p&gt;What makes MCP interesting for lab instruments is not the AI part. It is the standardization.&lt;/p&gt;

&lt;p&gt;MCP gives us a uniform interface layer. Instead of teaching every AI agent about SiLA2 commands, OPC-UA node structures, and SCPI syntax, we wrap each instrument in an MCP server. The agent sees a clean set of tools:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@mcp_server.tool&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;aspirate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;well&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;volume_ul&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Aspirate liquid from a specified well.

    Args:
        well: Well position (e.g., &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;A1&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;, &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;B3&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;)
        volume_ul: Volume in microliters (0.1 - 1000)
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="c1"&gt;# Translate to instrument-specific protocol
&lt;/span&gt;    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hardware_api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute_aspirate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;well&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;volume_ul&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Aspirated &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;volume_ul&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; uL from &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;well&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="nd"&gt;@mcp_server.tool&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;dispense&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;well&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;volume_ul&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Dispense liquid into a specified well.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hardware_api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute_dispense&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;well&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;volume_ul&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Dispensed &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;volume_ul&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; uL into &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;well&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="nd"&gt;@mcp_server.tool&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_plate_status&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Get current status of all wells on the plate.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;hardware_api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read_plate_map&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent does not need to know whether the instrument speaks SiLA2 or serial commands. It calls &lt;code&gt;aspirate(well="A1", volume_ul=50.0)&lt;/code&gt; and the MCP server handles the translation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture: From Natural Language to Hardware
&lt;/h2&gt;

&lt;p&gt;We built this architecture in LiquidBridge, our open demo for AI-controlled liquid handling. Here is how it works:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Scientist: "Transfer 50 uL from wells A1-A4 to wells B1-B4"
                            │
                            ▼
                    ┌───────────────┐
                    │   AI Agent    │  Plans multi-step workflow
                    │   (CrewAI)    │  Validates against constraints
                    └───────┬───────┘
                            │
                            ▼
                    ┌───────────────┐
                    │  MCP Server   │  Translates tool calls to
                    │  (FastMCP)    │  instrument protocol
                    └───────┬───────┘
                            │
                            ▼
                    ┌───────────────┐
                    │  Hardware API │  SiLA2 / OPC-UA / Serial
                    │  (FastAPI)    │  commands to instrument
                    └───────┬───────┘
                            │
                            ▼
                    ┌───────────────┐
                    │   Liquid      │  Physical execution
                    │   Handler     │
                    └───────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key design decisions:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MCP as the integration layer, not the control layer.&lt;/strong&gt; The MCP server does not talk directly to hardware. It calls a Hardware API that handles the actual instrument protocol. This separation means we can swap instruments without touching the agent or MCP layer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One MCP server per instrument class.&lt;/strong&gt; A liquid handler MCP server exposes tools for aspiration, dispensing, tip handling, and plate management. A plate reader MCP server exposes tools for reading absorbance, fluorescence, and luminescence. Each server is a self-contained adapter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agent plans, human approves, hardware executes.&lt;/strong&gt; The AI agent receives the natural language request, breaks it into a sequence of MCP tool calls, and presents the plan for approval before any physical action happens.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Human-in-the-Loop Problem
&lt;/h2&gt;

&lt;p&gt;This is where lab instruments diverge from typical MCP use cases. When an AI agent calls a tool to query a database, the worst case is a bad query that returns wrong data. When an AI agent calls a tool to aspirate liquid from a well, the worst case is a contaminated sample, a broken tip, or a ruined experiment.&lt;/p&gt;

&lt;p&gt;In regulated environments - GxP, GLP, GMP - every action on a sample must be traceable. An AI agent making autonomous decisions about physical operations is a non-starter for compliance.&lt;/p&gt;

&lt;p&gt;Our approach: &lt;strong&gt;the agent proposes, the human disposes.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent generates plan:
  1. Pick up tips from rack position 1
  2. Aspirate 50 uL from A1
  3. Dispense 50 uL into B1
  4. Aspirate 50 uL from A2
  5. Dispense 50 uL into B2
  ... (8 steps total)

Scientist reviews:  [Approve] [Modify] [Reject]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The UI shows the full execution plan with volumes, positions, and sequence. The scientist reviews and either approves the entire plan, modifies specific steps, or rejects it and re-describes their intent. Only after explicit approval does the agent execute against the hardware.&lt;/p&gt;

&lt;p&gt;Every step is logged with timestamps, the original prompt, the agent's reasoning, the human's decision, and the hardware response. This gives you an audit trail that satisfies GxP requirements - arguably a better audit trail than manual pipetting, where documentation depends on the scientist remembering to record each step.&lt;/p&gt;

&lt;h2&gt;
  
  
  What We Learned Building This
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Tool granularity matters more than you think.&lt;/strong&gt; Our first version exposed fine-grained tools - &lt;code&gt;move_to_position&lt;/code&gt;, &lt;code&gt;lower_tips&lt;/code&gt;, &lt;code&gt;aspirate&lt;/code&gt;, &lt;code&gt;raise_tips&lt;/code&gt;. The agent struggled with sequencing. Our second version exposed workflow-level tools - &lt;code&gt;aspirate_from_well&lt;/code&gt;, &lt;code&gt;dispense_to_well&lt;/code&gt;, &lt;code&gt;pick_up_tips&lt;/code&gt; - where each tool encapsulates a safe sequence of hardware actions. The agent's success rate went from ~60% to over 95%.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;State management is fundamentally different from software tools.&lt;/strong&gt; A database MCP server is stateless - each query is independent. A liquid handler MCP server is deeply stateful. The agent needs to know: are tips loaded? What volume is currently held? Which wells have been used? We solved this by making the MCP server expose a &lt;code&gt;get_instrument_state&lt;/code&gt; resource that the agent checks before planning.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Error handling must be physical-world-aware.&lt;/strong&gt; Software errors are recoverable - retry the API call. Hardware errors have physical consequences. A tip collision can damage the instrument. Our MCP server implements pre-execution validation: before calling the hardware, it checks positions, volumes, and tip status against known constraints.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Next: The Lab of 2030
&lt;/h2&gt;

&lt;p&gt;We are building toward a future where any lab instrument with a digital interface can be wrapped as an MCP server and controlled through natural language. Not to replace scientists - to give them a better interface to their own equipment.&lt;/p&gt;

&lt;p&gt;The technical foundation is here. MCP provides the standardization. AI agents provide the natural language understanding. Human-in-the-loop provides the safety. What is missing is coverage - more instrument protocols wrapped, more edge cases handled, more labs running this in production.&lt;/p&gt;

&lt;p&gt;If you are building instrument control software, or if you are a scientist frustrated with vendor GUIs, this is the architecture to watch. The protocol adapter pattern - instrument protocol to MCP to AI agent - works. We have shipped it. And we are open to collaborating with instrument manufacturers who want to make their hardware AI-accessible.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Iacob is the Technical Lead at &lt;a href="https://qpillars.com" rel="noopener noreferrer"&gt;QPillars&lt;/a&gt;, a Zurich-based team building agentic AI for scientific instruments. QPillars delivers instrument control systems, data platforms, and AI integration for biotech and medtech companies. Learn more about &lt;a href="https://qpillars.com/liquidbridge" rel="noopener noreferrer"&gt;LiquidBridge&lt;/a&gt; or reach out at &lt;a href="mailto:iacob@qpillars.com"&gt;iacob@qpillars.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>automation</category>
      <category>python</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
