Skip to content

Agents (MCP)

galois-edge exposes every connected instrument as a typed Model Context Protocol (MCP) tool. Point any MCP-capable agent at the daemon and it sees per-instrument typed tools (keithley_2400__source_voltage, siemens_s71200__read_holding_register, dps150__set_voltage) plus a small set of generic discovery, execute, sweep, and stream tools — same shape, same auth, same audit log as the gRPC surface.

The MCP listener is enabled by default. After install the daemon binds streamable-HTTP on 127.0.0.1:8767/mcp; tailnet members reach it at http://<edge>.tail-1234.ts.net:8767/mcp.

The agent ecosystem fragmented into vendor-specific tool-use schemas (Anthropic tool use, OpenAI function calling, LangChain tools, …). MCP is the one wire protocol every major framework now consumes: Anthropic’s mcp_servers API connector, OpenAI Agents SDK, Claude Desktop, Cursor, LangGraph, LlamaIndex. Implementing MCP once gets the daemon into all of them with no per-framework glue.

Three tool categories, all on the same endpoint:

CategoryExamplesComes from
Static tools (always present, 13 in total)list_instruments, get_capabilities, scan_instruments, list_profiles, get_status, execute_command, execute_sequence, send_scpi, start_sweep, get_sweep_status, stop_sweep, start_stream, stop_streamHardcoded in mcp/tools/
Dynamic per-instrument toolskeithley_2400__source_voltage, keysight_34461a__measure_voltage_dc, siemens_s71200__read_holding_registerGenerated at runtime from the matched profile’s command catalogue
Dynamic per-SDK toolsdps150_wrapper__set_voltage, digilent_dwf_wrapper__configure_oscilloscopeGenerated from each sdk_wrappers/*.py module that declares MCP_TOOL_SPECS

Agents typically lead with list_instruments + get_capabilities to discover what’s reachable, then call the typed per-instrument tools. The static execute_command is the universal escape hatch — it works against every matched instrument and is what you’d target if you didn’t want to enumerate dynamic tools first.

Three properties that make this first-class

Section titled “Three properties that make this first-class”

These aren’t generic MCP — they’re things the daemon does that most MCP servers don’t:

  • Runtime capability discovery. tools/list reflects every connected instrument with typed parameters, units, ranges, and is_dangerous flags pulled live from profile YAML. The agent doesn’t read a vendor manual to use a new oscilloscope — it reads the tool catalogue.
  • Hot-plug surfaces in milliseconds. Plug in a new oscilloscope. The daemon profile-matches it. notifications/tools/list_changed fires within ~2 s. The agent’s tool catalogue updates without a session restart. Unplug it, the per-instrument tools come back out.
  • Daemon-resident long-running state. start_sweep returns a handle and the ramp continues on the daemon. start_stream maps each measurement point to an MCP notifications/progress event. An agent session can drop, hand off, or sleep without stranding hardware mid-ramp.

There are two transports today:

Direct over the tailnet

The daemon binds streamable-HTTP on the local network (or the tailnet IP). Agents on the same tailnet dial it directly. Network membership is the auth boundary.

Set this up →

Through the cloud relay

https://cloud.galoislabs.ai/mcp/<edge_id> terminates streamable-HTTP at the cloud and tunnels JSON-RPC over the existing relay WebSocket. Per-call JWT scopes the tool surface.

Daemon side shipped (this release). Cloud side is in PR review — rolling out.

The daemon is identical in both cases. Phase 1 (direct) and Phase 2 (relay) are the same FastMCP server reached through different ingress.

The MCP server lands in three phases. Phases 1 and 2 (daemon side) and Phase 3 are all in this release; the cloud side of the relay path is in PR review.

PhaseWhat it gives youStatus
Phase 1 — FastMCP server with static tool surface13 static tools at :8767/mcp, reachable on the tailnetShipped
Phase 2 — relay envelope + JWT validation (daemon side)Daemon validates Galois-Caller-JWT against cached JWKS, enforces per-call ACLShipped (daemon); cloud termination at cloud.galoislabs.ai/mcp/<edge_id> is in PR review
Phase 3 — dynamic tools, streaming, typed SDK wrappersPer-instrument typed tools, hot-plug tools/list_changed, real StreamMeasurement → progress notifications, typed SDK tools replacing opaque ProxySDKCallShipped