diff --git a/infra/lmxfakeproxy/LmxFakeProxy.csproj b/infra/lmxfakeproxy/LmxFakeProxy.csproj
new file mode 100644
index 0000000..1eaf063
--- /dev/null
+++ b/infra/lmxfakeproxy/LmxFakeProxy.csproj
@@ -0,0 +1,17 @@
+
+
+ net10.0
+ LmxFakeProxy
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
+
diff --git a/infra/lmxfakeproxy/Program.cs b/infra/lmxfakeproxy/Program.cs
new file mode 100644
index 0000000..933d130
--- /dev/null
+++ b/infra/lmxfakeproxy/Program.cs
@@ -0,0 +1,5 @@
+var builder = WebApplication.CreateBuilder(args);
+builder.Services.AddGrpc();
+var app = builder.Build();
+app.MapGet("/", () => "LmxFakeProxy is running");
+app.Run();
diff --git a/infra/lmxfakeproxy/Protos/scada.proto b/infra/lmxfakeproxy/Protos/scada.proto
new file mode 100644
index 0000000..fc327aa
--- /dev/null
+++ b/infra/lmxfakeproxy/Protos/scada.proto
@@ -0,0 +1,166 @@
+syntax = "proto3";
+
+option csharp_namespace = "LmxFakeProxy.Grpc";
+
+package scada;
+
+// The SCADA service definition
+service ScadaService {
+ // Connection management
+ rpc Connect(ConnectRequest) returns (ConnectResponse);
+ rpc Disconnect(DisconnectRequest) returns (DisconnectResponse);
+ rpc GetConnectionState(GetConnectionStateRequest) returns (GetConnectionStateResponse);
+
+ // Read operations
+ rpc Read(ReadRequest) returns (ReadResponse);
+ rpc ReadBatch(ReadBatchRequest) returns (ReadBatchResponse);
+
+ // Write operations
+ rpc Write(WriteRequest) returns (WriteResponse);
+ rpc WriteBatch(WriteBatchRequest) returns (WriteBatchResponse);
+ rpc WriteBatchAndWait(WriteBatchAndWaitRequest) returns (WriteBatchAndWaitResponse);
+
+ // Subscription operations (server streaming) - now streams VtqMessage directly
+ rpc Subscribe(SubscribeRequest) returns (stream VtqMessage);
+
+ // Authentication
+ rpc CheckApiKey(CheckApiKeyRequest) returns (CheckApiKeyResponse);
+}
+
+// === CONNECTION MESSAGES ===
+
+message ConnectRequest {
+ string client_id = 1;
+ string api_key = 2;
+}
+
+message ConnectResponse {
+ bool success = 1;
+ string message = 2;
+ string session_id = 3;
+}
+
+message DisconnectRequest {
+ string session_id = 1;
+}
+
+message DisconnectResponse {
+ bool success = 1;
+ string message = 2;
+}
+
+message GetConnectionStateRequest {
+ string session_id = 1;
+}
+
+message GetConnectionStateResponse {
+ bool is_connected = 1;
+ string client_id = 2;
+ int64 connected_since_utc_ticks = 3;
+}
+
+// === VTQ MESSAGE ===
+
+message VtqMessage {
+ string tag = 1;
+ string value = 2;
+ int64 timestamp_utc_ticks = 3;
+ string quality = 4; // "Good", "Uncertain", "Bad"
+}
+
+// === READ MESSAGES ===
+
+message ReadRequest {
+ string session_id = 1;
+ string tag = 2;
+}
+
+message ReadResponse {
+ bool success = 1;
+ string message = 2;
+ VtqMessage vtq = 3;
+}
+
+message ReadBatchRequest {
+ string session_id = 1;
+ repeated string tags = 2;
+}
+
+message ReadBatchResponse {
+ bool success = 1;
+ string message = 2;
+ repeated VtqMessage vtqs = 3;
+}
+
+// === WRITE MESSAGES ===
+
+message WriteRequest {
+ string session_id = 1;
+ string tag = 2;
+ string value = 3;
+}
+
+message WriteResponse {
+ bool success = 1;
+ string message = 2;
+}
+
+message WriteItem {
+ string tag = 1;
+ string value = 2;
+}
+
+message WriteResult {
+ string tag = 1;
+ bool success = 2;
+ string message = 3;
+}
+
+message WriteBatchRequest {
+ string session_id = 1;
+ repeated WriteItem items = 2;
+}
+
+message WriteBatchResponse {
+ bool success = 1;
+ string message = 2;
+ repeated WriteResult results = 3;
+}
+
+message WriteBatchAndWaitRequest {
+ string session_id = 1;
+ repeated WriteItem items = 2;
+ string flag_tag = 3;
+ string flag_value = 4;
+ int32 timeout_ms = 5;
+ int32 poll_interval_ms = 6;
+}
+
+message WriteBatchAndWaitResponse {
+ bool success = 1;
+ string message = 2;
+ repeated WriteResult write_results = 3;
+ bool flag_reached = 4;
+ int32 elapsed_ms = 5;
+}
+
+// === SUBSCRIPTION MESSAGES ===
+
+message SubscribeRequest {
+ string session_id = 1;
+ repeated string tags = 2;
+ int32 sampling_ms = 3;
+}
+
+// Note: Subscribe RPC now streams VtqMessage directly (defined above)
+
+// === AUTHENTICATION MESSAGES ===
+
+message CheckApiKeyRequest {
+ string api_key = 1;
+}
+
+message CheckApiKeyResponse {
+ bool is_valid = 1;
+ string message = 2;
+}
diff --git a/infra/lmxfakeproxy/tests/LmxFakeProxy.Tests/LmxFakeProxy.Tests.csproj b/infra/lmxfakeproxy/tests/LmxFakeProxy.Tests/LmxFakeProxy.Tests.csproj
new file mode 100644
index 0000000..580a665
--- /dev/null
+++ b/infra/lmxfakeproxy/tests/LmxFakeProxy.Tests/LmxFakeProxy.Tests.csproj
@@ -0,0 +1,20 @@
+
+
+ net10.0
+ LmxFakeProxy.Tests
+ enable
+ enable
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+