How to build an MCP (Model Context Protocol) Tool that exposes production KPIs and historical data to AI models, enabling intelligent analysis of industrial processes.
Table of Contents maxLevel 2 minLevel 2 indent 10px exclude Tutorial style none
Navigate to
ProductionData
Tag.ProductionRate
Tag.Efficiency
Tag.QualityScore
Tag.DowntimeMinutes
KPICalculator
csharp
public double CalculateOEE(double availability, double performance, double quality)
{
return availability * performance * quality * 100;
}
public double GetAverageProduction(DateTime startTime, DateTime endTime)
{
// Calculate average production rate over period
double totalProduction = @Tag.TotalUnits;
double hours = (endTime - startTime).TotalHours;
return hours > 0 ? totalProduction / hours : 0;
}
public string GetProductionStatus()
{
if (@Tag.ProductionRate > 100)
return "High Performance";
else if (@Tag.ProductionRate > 80)
return "Normal";
else
return "Below Target";
}
ProductionMCPTool
csharp
[MCPMethod(Description = "Get current production KPIs")]
public object GetCurrentKPIs()
{
return new {
ProductionRate = @Tag.ProductionRate,
Efficiency = @Tag.Efficiency,
OEE = @Script.Class.KPICalculator.CalculateOEE(
@Tag.Availability, @Tag.Performance, @Tag.Quality),
Status = @Script.Class.KPICalculator.GetProductionStatus(),
Timestamp = DateTime.Now
};
}
[MCPMethod(Description = "Get production history for specified hours")]
public object GetProductionHistory(
[MCPParameter(Description = "Hours to look back")] int hours)
{
var endTime = DateTime.Now;
var startTime = endTime.AddHours(-hours);
// Query historian
var data = @Historian.Table.ProductionData.GetData(startTime, endTime);
return new {
Period = $"Last {hours} hours",
AverageRate = @Script.Class.KPICalculator.GetAverageProduction(startTime, endTime),
TotalUnits = @Tag.TotalUnits,
DataPoints = data.Rows.Count
};
}
[MCPMethod(Description = "Analyze production trend")]
public string AnalyzeProductionTrend(
[MCPParameter(Description = "Time period in hours")] int periodHours)
{
var current = @Tag.ProductionRate;
var average = @Script.Class.KPICalculator.GetAverageProduction(
DateTime.Now.AddHours(-periodHours), DateTime.Now);
if (current > average * 1.1)
return "Trending Up - Production improving";
else if (current < average * 0.9)
return "Trending Down - Requires attention";
else
return "Stable - Within normal range";
}
This tutorial demonstrates using ML.NET 4.0 for real-time anomaly detection on sensor data using Script Tasks.
Prerequisites:
Tag.SensorValue
(Double) - Current readingTag.AnomalyScore
(Double) - Detection scoreTag.IsAnomaly
(Boolean) - Alert flagTag.Threshold
(Double) - Detection threshold (default: 0.3)AnomalyDetector
csharp
// Simple spike detection using ML.NET
using Microsoft.ML;
using Microsoft.ML.Data;
// Static ML context (initialized once)
if (@Tag.MLContext == null)
{
@Tag.MLContext = new MLContext(seed: 0);
@Tag.DetectionEngine = InitializeDetector();
}
// Data class for ML model
public class SensorData
{
public float Value { get; set; }
}
public class AnomalyPrediction
{
[VectorType(3)]
public double[] Prediction { get; set; }
}
// Initialize detector (runs once)
private ITransformer InitializeDetector()
{
var dataView = @Tag.MLContext.Data.LoadFromEnumerable(new List<SensorData>());
var pipeline = @Tag.MLContext.Transforms
.DetectSpikeBySsa(
outputColumnName: "Prediction",
inputColumnName: "Value",
confidence: 95,
pvalueHistoryLength: 30,
trainingWindowSize: 90,
seasonalityWindowSize: 30);
return pipeline.Fit(dataView);
}
// Detection logic (runs every second)
var currentValue = (float)@Tag.SensorValue;
var data = new SensorData { Value = currentValue };
var prediction = @Tag.DetectionEngine.Transform(
@Tag.MLContext.Data.LoadFromEnumerable(new[] { data }));
var result = @Tag.MLContext.Data
.CreateEnumerable<AnomalyPrediction>(prediction, false)
.First();
// Update tags with results
@Tag.AnomalyScore = result.Prediction[0]; // Spike score
@Tag.IsAnomaly = result.Prediction[0] > @Tag.Threshold;
// Log anomalies
if (@Tag.IsAnomaly)
{
@Alarm.GlobalSettings.AuditTrail.AddCustomMessage(
$"Anomaly detected: Sensor={currentValue:F2}, Score={result.Prediction[0]:F3}");
}
SensorSimulator
csharp
// Simulate normal sensor data with occasional spikes
Random rand = new Random();
double baseValue = 50.0;
double noise = rand.NextDouble() * 5 - 2.5;
// Inject anomaly occasionally (5% chance)
if (rand.NextDouble() < 0.05)
{
@Tag.SensorValue = baseValue + (rand.NextDouble() * 30 + 20); // Spike
}
else
{
@Tag.SensorValue = baseValue + noise; // Normal variation
}
Scripts → Classes
Click in the create a New Class button
In Create new Code, select MCPTool
Click OK
In the Script code, you can have multiple methods and they follow this format:
Code Block |
---|
[McpServerTool, Description("<This is the question>")]
public string <MethodName> (
[Description("<Description of the parameter>")] <Parameters>)
{
<Logic>
<Return>
} |
Example:
Code Block |
---|
[McpServerTool, Description("Performs concatenation of two input text values.")]
public string Concat(
[Description("The first text value to be used in the operation.")] string parameter1,
[Description("The second text value to be used in the operation, concatenated after the first.")] string parameter2)
{
return parameter1 + parameter2;
} |
The logic can process the data and return it as a string, so the AI will receive it.
Have Claude AI Desktop downloaded
Go in Settings → Developer → Edit Config and select the ”claude_desktop_config.json”
This .json should have the following content:
Code Block |
---|
{
"mcpServers": {
"<SolutionName>": {
"command": "<ProductPath>\\fx-10\\net8.0\\TMCPServerStdio\\TMCPServerStdio.exe",
"args": [ "/host:127.0.0.1", "/port:<port>" ],
"transport": "stdio"
}
}
} |
In the Developer setting it shoud show “running” and when you open a new chat in “Search and Tools” you will see the name of your solution there.
You can query any method in a Claude chat. e.g: “What is the tag value?” and it returns the value requested.
Besides the method you created in the script, you can ask general information about the solution, like:
Get tag historian
Get alarm online
Get value
These tutorials provide simple, practical starting points for both MCP Tools
and ML.NET integration,focusing on real industrial scenarios while keeping complexity minimal for learning purposes.
Page Tree | ||||
---|---|---|---|---|
|