diff --git a/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.MTConnect.Contracts/MTConnectDriverOptions.cs b/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.MTConnect.Contracts/MTConnectDriverOptions.cs
new file mode 100644
index 00000000..8b9a9031
--- /dev/null
+++ b/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.MTConnect.Contracts/MTConnectDriverOptions.cs
@@ -0,0 +1,91 @@
+namespace ZB.MOM.WW.OtOpcUa.Driver.MTConnect;
+
+///
+/// MTConnect Agent driver configuration. Bound from the driver's DriverConfig JSON at
+/// DriverHost.RegisterAsync. The driver polls a remote MTConnect Agent's REST endpoints
+/// (/probe, /current, /sample) rooted at and maps
+/// each returned DataItem into an OPC UA variable per .
+///
+public sealed class MTConnectDriverOptions
+{
+ ///
+ /// Gets the MTConnect Agent's base URI (e.g. http://agent:5000). Required — the
+ /// driver appends the standard Agent request paths (/probe, /current,
+ /// /sample) to this base.
+ ///
+ public required string AgentUri { get; init; }
+
+ ///
+ /// Optional device-name scope. When set, requests are narrowed to
+ /// {AgentUri}/{DeviceName}/... so a multi-device Agent only serves one device's
+ /// DataItems through this driver instance. Default null = agent-wide (all devices).
+ ///
+ public string? DeviceName { get; init; }
+
+ ///
+ /// Per-call HTTP deadline, in milliseconds, applied to every Agent request
+ /// (/probe, /current, /sample). Default 5000 — long enough for
+ /// a large device probe response over a LAN, short enough that a hung Agent surfaces as a
+ /// failed poll rather than wedging the driver.
+ ///
+ public int RequestTimeoutMs { get; init; } = 5000;
+
+ ///
+ /// The interval query parameter (milliseconds) passed to the Agent's /sample
+ /// streaming request — the minimum time the Agent waits between successive chunks of the
+ /// response. Default 1000; must be non-zero so the sample pump cannot spin the
+ /// connection into a busy-loop.
+ ///
+ public int SampleIntervalMs { get; init; } = 1000;
+
+ ///
+ /// The count query parameter passed to the Agent's /sample request — the
+ /// maximum number of DataItem observations returned per chunk. Default 1000, the
+ /// MTConnect Agent's own conventional default.
+ ///
+ public int SampleCount { get; init; } = 1000;
+
+ ///
+ /// The heartbeat query parameter (milliseconds) passed to the Agent's /sample
+ /// streaming request — the Agent sends an empty chunk after this much idle time so the
+ /// client can detect a silently-stalled connection. Default 10000, matching the
+ /// MTConnect Agent's own conventional default; must be non-zero or a quiet connection can
+ /// never be distinguished from a dead one.
+ ///
+ public int HeartbeatMs { get; init; } = 10000;
+
+ ///
+ /// Background connectivity-probe settings. When
+ /// is true the driver periodically issues a cheap /probe request and raises
+ /// OnHostStatusChanged on Running ↔ Stopped transitions.
+ ///
+ public MTConnectProbeOptions Probe { get; init; } = new();
+
+ ///
+ /// Reconnect backoff settings used after a failed Agent request or a dropped
+ /// /sample streaming connection.
+ ///
+ public MTConnectReconnectOptions Reconnect { get; init; } = new();
+}
+
+/// Background connectivity-probe knobs, mirroring ModbusProbeOptions.
+public sealed class MTConnectProbeOptions
+{
+ /// Gets a value indicating whether probing is enabled.
+ public bool Enabled { get; init; } = true;
+ /// Gets the interval between probe requests.
+ public TimeSpan Interval { get; init; } = TimeSpan.FromSeconds(5);
+ /// Gets the probe request timeout.
+ public TimeSpan Timeout { get; init; } = TimeSpan.FromSeconds(2);
+}
+
+/// Geometric-backoff settings for the post-failure reconnect loop, mirroring ModbusReconnectOptions.
+public sealed class MTConnectReconnectOptions
+{
+ /// Delay before the first reconnect attempt, in milliseconds. Default 0 = immediate.
+ public int MinBackoffMs { get; init; } = 0;
+ /// Upper bound on the geometric backoff sequence, in milliseconds.
+ public int MaxBackoffMs { get; init; } = 30000;
+ /// Multiplier applied each retry. Default 2.0 doubles each step.
+ public double BackoffMultiplier { get; init; } = 2.0;
+}
diff --git a/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.MTConnect.Contracts/MTConnectTagDefinition.cs b/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.MTConnect.Contracts/MTConnectTagDefinition.cs
new file mode 100644
index 00000000..c956f809
--- /dev/null
+++ b/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.MTConnect.Contracts/MTConnectTagDefinition.cs
@@ -0,0 +1,49 @@
+using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
+
+namespace ZB.MOM.WW.OtOpcUa.Driver.MTConnect;
+
+///
+/// One MTConnect-backed OPC UA variable. Each authored tag binds a single Agent DataItem by
+/// its id attribute (); the driver looks up the observation's
+/// current value from the Agent's /current snapshot / /sample stream by that id.
+///
+///
+/// The MTConnect DataItem's id attribute (the Agent's /probe response). This is
+/// the driver's reference for read/subscribe — MTConnect is a read-only source protocol, so
+/// there is no corresponding write path.
+///
+/// Logical data type the DataItem's value is coerced to.
+///
+/// When true, the tag is exposed as an OPC UA array (e.g. an MTConnect
+/// PathPosition / vector-valued sample). Default false = scalar.
+///
+///
+/// Element count when is true; ignored for scalar tags. Default
+/// 0.
+///
+///
+/// The DataItem's MTConnect category attribute — SAMPLE, EVENT, or
+/// CONDITION. Optional metadata carried through for browse / display; not consulted by
+/// the value-mapping path. Default null.
+///
+///
+/// The DataItem's MTConnect type attribute (e.g. POSITION, EXECUTION).
+/// Optional metadata. Default null.
+///
+///
+/// The DataItem's MTConnect subType attribute (e.g. ACTUAL, COMMANDED).
+/// Optional metadata. Default null.
+///
+///
+/// The DataItem's MTConnect units attribute (e.g. MILLIMETER,
+/// REVOLUTION/MINUTE). Optional metadata. Default null.
+///
+public sealed record MTConnectTagDefinition(
+ string FullName,
+ DriverDataType DriverDataType,
+ bool IsArray = false,
+ int ArrayDim = 0,
+ string? MtCategory = null,
+ string? MtType = null,
+ string? MtSubType = null,
+ string? Units = null);
diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.MTConnect.Tests/MTConnectDriverOptionsTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.MTConnect.Tests/MTConnectDriverOptionsTests.cs
new file mode 100644
index 00000000..0b77db18
--- /dev/null
+++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.MTConnect.Tests/MTConnectDriverOptionsTests.cs
@@ -0,0 +1,80 @@
+using Shouldly;
+using Xunit;
+
+namespace ZB.MOM.WW.OtOpcUa.Driver.MTConnect.Tests;
+
+///
+/// Task 2 coverage for / :
+/// defaults are sane (non-zero timers, probe on) and the required-field shape (AgentUri) binds.
+///
+[Trait("Category", "Unit")]
+public sealed class MTConnectDriverOptionsTests
+{
+ /// Default sample/heartbeat timers are non-zero and the probe is enabled by default.
+ [Fact]
+ public void Options_default_sample_and_heartbeat_are_sane()
+ {
+ var o = new MTConnectDriverOptions { AgentUri = "http://agent:5000" };
+ o.SampleIntervalMs.ShouldBeGreaterThan(0);
+ o.HeartbeatMs.ShouldBeGreaterThan(0);
+ o.Probe.Enabled.ShouldBeTrue();
+ }
+
+ /// AgentUri is the only required field; DeviceName scope defaults to unset (agent-wide).
+ [Fact]
+ public void Options_agent_uri_is_required_device_name_defaults_to_null()
+ {
+ var o = new MTConnectDriverOptions { AgentUri = "http://agent:5000" };
+ o.AgentUri.ShouldBe("http://agent:5000");
+ o.DeviceName.ShouldBeNull();
+ }
+
+ /// RequestTimeoutMs and SampleCount default to sane, non-zero, non-wedging values.
+ [Fact]
+ public void Options_request_timeout_and_sample_count_are_non_zero()
+ {
+ var o = new MTConnectDriverOptions { AgentUri = "http://agent:5000" };
+ o.RequestTimeoutMs.ShouldBeGreaterThan(0);
+ o.SampleCount.ShouldBeGreaterThan(0);
+ }
+
+ /// Probe sub-options mirror ModbusProbeOptions' shape: Enabled/Interval/Timeout, both non-zero.
+ [Fact]
+ public void Probe_defaults_have_non_zero_interval_and_timeout()
+ {
+ var probe = new MTConnectDriverOptions { AgentUri = "http://agent:5000" }.Probe;
+ probe.Interval.ShouldBeGreaterThan(TimeSpan.Zero);
+ probe.Timeout.ShouldBeGreaterThan(TimeSpan.Zero);
+ }
+
+ /// Reconnect sub-options default to a bounded, non-degenerate geometric backoff.
+ [Fact]
+ public void Reconnect_defaults_bound_backoff_growth()
+ {
+ var reconnect = new MTConnectDriverOptions { AgentUri = "http://agent:5000" }.Reconnect;
+ reconnect.MaxBackoffMs.ShouldBeGreaterThan(reconnect.MinBackoffMs);
+ reconnect.BackoffMultiplier.ShouldBeGreaterThan(1.0);
+ }
+
+ /// MTConnectTagDefinition round-trips its positional fields, including MTConnect metadata.
+ [Fact]
+ public void TagDefinition_carries_dataItemId_and_mtconnect_metadata()
+ {
+ var tag = new MTConnectTagDefinition(
+ FullName: "dtop_2",
+ DriverDataType: ZB.MOM.WW.OtOpcUa.Core.Abstractions.DriverDataType.Float64,
+ MtCategory: "SAMPLE",
+ MtType: "POSITION",
+ MtSubType: "ACTUAL",
+ Units: "MILLIMETER");
+
+ tag.FullName.ShouldBe("dtop_2");
+ tag.DriverDataType.ShouldBe(ZB.MOM.WW.OtOpcUa.Core.Abstractions.DriverDataType.Float64);
+ tag.IsArray.ShouldBeFalse();
+ tag.ArrayDim.ShouldBe(0);
+ tag.MtCategory.ShouldBe("SAMPLE");
+ tag.MtType.ShouldBe("POSITION");
+ tag.MtSubType.ShouldBe("ACTUAL");
+ tag.Units.ShouldBe("MILLIMETER");
+ }
+}