Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.


Page properties
hiddentrue
idconnector-metadata


Property

Value

Sector

AI Analysis & MCP

Group

Cloud Services

Connector

MCP Tools  Serve

Name

MCPServer



Enable AI-powered industrial automation through Model Context Protocol integration.

  • Name: MCPServer
  • Version: 1.0.0.0
  • Interface: TCP/IP
  • Configuration:
    • Scripts / Classes

Table of Contents
maxLevel2
minLevel2
stylenone


Overview

The MCP (Model Context Protocol) Tool Connector bridges FrameworX solutions with AI language models, enabling intelligent automation assistance while maintaining industrial-grade safety and determinism. This connector exposes your solution's data and functionality as structured tools that AI models can invoke with parameters, not just generate text responses.

Key Capabilities

  • Structured AI Integration - Expose specific methods and functions to AI models with type-safe parameters
  • Real-time Data Access - Query live tag values, historian data, and alarm states through AI
  • Bi-directional Communication - AI can both read from and write to your industrial systems (with appropriate safeguards)
  • Platform Agnostic - Works with Claude, GPT, and other MCP-compatible AI models


Integration Architecture

HTML
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 500">
  <defs>
    <!-- Gradients -->
    <linearGradient id="aiGradient" x1="0%" y1="0%" x2="100%" y2="100%">
      <stop offset="0%" style="stop-color:#667eea"/>
      <stop offset="100%" style="stop-color:#764ba2"/>
    </linearGradient>
    <linearGradient id="mcpGradient" x1="0%" y1="0%" x2="100%" y2="100%">
      <stop offset="0%" style="stop-color:#f093fb"/>
      <stop offset="100%" style="stop-color:#f5576c"/>
    </linearGradient>
    <linearGradient id="fwxGradient" x1="0%" y1="0%" x2="100%" y2="100%">
      <stop offset="0%" style="stop-color:#4facfe"/>
      <stop offset="100%" style="stop-color:#00f2fe"/>
    </linearGradient>
    <linearGradient id="methodGradient" x1="0%" y1="0%" x2="100%" y2="100%">
      <stop offset="0%" style="stop-color:#43e97b"/>
      <stop offset="100%" style="stop-color:#38f9d7"/>
    </linearGradient>
    
    <!-- Shadow filter -->
    <filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
      <feDropShadow dx="3" dy="3" stdDeviation="4" flood-opacity="0.2"/>
    </filter>
    
    <!-- Arrow marker -->
    <marker id="arrowhead" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
      <polygon points="0 0, 10 3.5, 0 7" fill="#6b7280"/>
    </marker>
  </defs>
  
  <!-- Background -->
  <rect width="800" height="500" fill="#f8fafc"/>
  
  <!-- Title -->
  <text x="400" y="40" text-anchor="middle" font-family="Arial, sans-serif" font-size="22" font-weight="bold" fill="#1e293b">MCP Protocol Architecture</text>
  
  <!-- AI Model Box -->
  <rect x="50" y="100" width="180" height="100" rx="12" fill="url(#aiGradient)" filter="url(#shadow)"/>
  <text x="140" y="145" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" font-weight="bold" fill="white">AI Model</text>
  <text x="140" y="170" text-anchor="middle" font-family="Arial, sans-serif" font-size="13" fill="rgba(255,255,255,0.9)">(Claude / GPT)</text>
  
  <!-- MCP Protocol Box -->
  <rect x="310" y="100" width="180" height="100" rx="12" fill="url(#mcpGradient)" filter="url(#shadow)"/>
  <text x="400" y="145" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" font-weight="bold" fill="white">MCP Protocol</text>
  <text x="400" y="170" text-anchor="middle" font-family="Arial, sans-serif" font-size="12" fill="rgba(255,255,255,0.9)">Model Context Protocol</text>
  
  <!-- FrameworX Box -->
  <rect x="570" y="100" width="180" height="100" rx="12" fill="url(#fwxGradient)" filter="url(#shadow)"/>
  <text x="660" y="145" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" font-weight="bold" fill="white">FrameworX</text>
  <text x="660" y="170" text-anchor="middle" font-family="Arial, sans-serif" font-size="13" fill="rgba(255,255,255,0.9)">Solution</text>
  
  <!-- Bidirectional Arrows between boxes -->
  <!-- AI to MCP -->
  <line x1="230" y1="140" x2="305" y2="140" stroke="#6b7280" stroke-width="2.5" marker-end="url(#arrowhead)"/>
  <line x1="305" y1="160" x2="230" y2="160" stroke="#6b7280" stroke-width="2.5" marker-end="url(#arrowhead)"/>
  
  <!-- MCP to FrameworX -->
  <line x1="490" y1="140" x2="565" y2="140" stroke="#6b7280" stroke-width="2.5" marker-end="url(#arrowhead)"/>
  <line x1="565" y1="160" x2="490" y2="160" stroke="#6b7280" stroke-width="2.5" marker-end="url(#arrowhead)"/>
  
  <!-- Vertical Arrow from FrameworX to Methods -->
  <line x1="660" y1="200" x2="660" y2="260" stroke="#6b7280" stroke-width="2.5" marker-end="url(#arrowhead)"/>
  
  <!-- Structured Methods Label - positioned under FrameworX -->
  <rect x="540" y="270" width="240" height="35" rx="8" fill="#1e293b" filter="url(#shadow)"/>
  <text x="660" y="294" text-anchor="middle" font-family="Arial, sans-serif" font-size="14" font-weight="bold" fill="white">Structured Methods</text>
  
  <!-- Method boxes - repositioned to align under FrameworX -->
  <!-- Tag Data Access -->
  <rect x="80" y="340" width="150" height="70" rx="10" fill="url(#methodGradient)" filter="url(#shadow)"/>
  <image href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%23065f46' stroke-width='2'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-7 7a2 2 0 01-2.828 0l-7-7A1.994 1.994 0 013 12V7a4 4 0 014-4z'/%3E%3C/svg%3E" x="130" y="350" width="24" height="24"/>
  <text x="155" y="395" text-anchor="middle" font-family="Arial, sans-serif" font-size="12" font-weight="bold" fill="#065f46">Tag Data Access</text>
  
  <!-- Historian Queries -->
  <rect x="250" y="340" width="150" height="70" rx="10" fill="url(#methodGradient)" filter="url(#shadow)"/>
  <image href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%23065f46' stroke-width='2'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4m0 5c0 2.21-3.582 4-8 4s-8-1.79-8-4'/%3E%3C/svg%3E" x="300" y="350" width="24" height="24"/>
  <text x="325" y="395" text-anchor="middle" font-family="Arial, sans-serif" font-size="12" font-weight="bold" fill="#065f46">Historian Queries</text>
  
  <!-- Alarm Monitoring -->
  <rect x="420" y="340" width="150" height="70" rx="10" fill="url(#methodGradient)" filter="url(#shadow)"/>
  <image href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%23065f46' stroke-width='2'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9'/%3E%3C/svg%3E" x="470" y="350" width="24" height="24"/>
  <text x="495" y="395" text-anchor="middle" font-family="Arial, sans-serif" font-size="12" font-weight="bold" fill="#065f46">Alarm Monitoring</text>
  
  <!-- Real-Time Events -->
  <rect x="590" y="340" width="150" height="70" rx="10" fill="url(#methodGradient)" filter="url(#shadow)"/>
  <image href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%23065f46' stroke-width='2'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M13 10V3L4 14h7v7l9-11h-7z'/%3E%3C/svg%3E" x="640" y="350" width="24" height="24"/>
  <text x="665" y="395" text-anchor="middle" font-family="Arial, sans-serif" font-size="12" font-weight="bold" fill="#065f46">Real-Time>Custom Events<Methods</text>
  
  <!-- Connecting lines from Structured Methods label to method boxes -->
  <path d="M 540 305 Q 400 322 155 340" stroke="#94a3b8" stroke-width="1.5" fill="none" stroke-dasharray="4,3"/>
  <path d="M 560 305 Q 450 322 325 340" stroke="#94a3b8" stroke-width="1.5" fill="none" stroke-dasharray="4,3"/>
  <path d="M 640 305 Q 580 322 495 340" stroke="#94a3b8" stroke-width="1.5" fill="none" stroke-dasharray="4,3"/>
  <path d="M 700 305 Q 700 322 665 340" stroke="#94a3b8" stroke-width="1.5" fill="none" stroke-dasharray="4,3"/>
  
</svg>




Technical Specifications

PropertyValue
NameMCP Tool
ProtocolModel Context Protocol (MCP)
Interfacestdio/HTTP
Runtime.NET 8.0
AI ModelsClaude
ConfigurationScripts → Classes

Prerequisites

  • FrameworX 10.1 or later
  • .NET 8.0 runtime
  • Claude Desktop or compatible MCP client
  • Network connectivity

Configuration Workflow

The first step is to run the solution, which will automatically start the MCP Server. The second step is to configure the client LLM to perform the queries.

According to the claude documentation, there are three ways of connection to the MCP Server:

  1. stdio
  2. HTTP
  3. SSE 

stdio

The following configuration uses stdio, which requires the MCP server to run on the same machine as the LLM. Therefore, if your solution is hosted on a remote machine, you must install the product in both environments: the local machine (where the LLM runs) and the remote machine (where the runtime is hosted).

Configure your AI client (e.g., Claude Desktop) to connect to the MCP server:

Code Block
{
  "mcpServers": {
    "YourSolution": {
      "command": "C:\\FrameworX\\fx-10\\net8.0\\TMCPServerStdio\\TMCPServerStdio.exe",
      "args": ["/host:127.0.0.1", "/port:3101"],
      "transport": "stdio"
    }
  }
}


Info

If you solution is Windows-only, the command should be "<ProductPath>\\fx-10\\TMCPServerStdio\\TMCPServerStdio.exe".

HTTP

This method was only tested with GitHub Copilot. Other LLMs should work as well, but have not been tested.

Program: TMCPServerHttp

Install Path: <ProductPath>\fx-10\net8.0\TMCPServerHttp\ (NET 8.0 Runtime required to execute TMCPServerHttp.dll)

LLM Setting 

Arguments in LLM Setting, example: .mcp.json (GitHub Copilot) or claude_desktop_config (ClaudeAI) (location may vary depending on the LLM)

  1. Url:<url>: Endpoint containg Host:Port. Ex: http://localhost:3000, https://192.168.20.2:3000
    When using certificate HTTP/SSL, the url must include "https"

  2. Headers: X_API_KEY (optional) used by authentication

MCP Server Setting

Arguments in TMCPServerHttp.json (located in C:\Users\Public\Documents\FrameworX\MachineSettings):

  1. X_API_KEY: (optional) used by authentication. It is a string password that will be required when client connects to the MCP server.

  2. /CertFileName:<filename>: Certificate file name. Used by HTTP/SSL. Work with “CertPass“.

  3. /CertPass:<pass>: Certificate password. Used by HTTP/SSL. Work with “CertFileName“.

  4. /CertHash:<hash>: Certificate Thumbprint. Used by HTTP/SSL. Located at: (StoreName.My, StoreLocation.LocalMachine)

  5. /ListenPort:<port>: Port to listen (endpoint). Default is 3000

  6. Runtime section:

    1. /Host<host>: Runtime Host/IP where runtime is running. Default is localhost

    2. /Port:<port>: Runtime Port where runtime is running. Default is 3101

    3. /UserName<name>: User name used by connection to runtime

    4. /Password:<pass>: User password used by connection to runtime

Multiple connections

To connect to several runtimes and/or listen several ports, call TMCPServerHttp with argument “/instance:<number>“.

  1. Arguments in section “4” must include “instance”.

  2. Example: TMCPServerHttp /instance:2 => X_API_KEY2, ListenPort2, Runtime2, etc…


Code Block
title.mcp.json (GitHub Copilot)
{
   "servers": {
    "FrameworX Runtime - HeaderLayout": {
      "type": "http",
      "url": "http://localhost:3000",
      "headers": {
        "X-API-KEY": ""
      }
    }
  }
}


Code Block
title.TMCPServerHttp.json
{
  "appSettings": {
    "X_API_KEY": "",
    "CertFileName": "",
    "CertPass": "",
    "CertHash": "",
    "ListenPort": "3000",
    "Runtime": {
      "Host": "localhost",
      "Port": "3101",
      "Username": "guest",
      "Password": ""
    }
  }
}

SSE

SSE configuration was not tested.

How to verify if the setting was done correctly

  1. Click in the LLM connector, you should see the <SolutionName> name.
  2. Go in Settings > Developer, and check if your solution is in a good state (running). (depends on the LLM).

Query Through AI

Once configured, the AI can access your solution data:

General questions

  • What is the Server.SystemMonitor.Uptime of BottlingLine MCP Demo?
  • Get value of Tag.Machine1.Temperature1

Alarm

  • Is there any active alarm, or has there been one recently? Any acknowledged?
  • Retrieve the alarms again, and check how many acknowledged alarms do we have? and how many are not?

Historian

  • Retrieve the historical Brewery/BrewHouse/Temperature values from today.
  • Show a trend visualization (only the trend) with the historical values of Brewery/BrewHouse/Temperature from today in JSX format
  • Get all the historical value from today and return the highest and the time that hapenned

Custom Methods (methods you created)

  • Get the last anomalies from the Bottling Line

Available Methods

When MCP server is running, by default you have three methods:

  1. Get Value
  2. Get Historian
  3. Get Alarms

And you could have many more, by just creating a custom method, for that follow the steps below:

  1. Navigate to Scripts → Classes
  2. Create new class, select MCP Tool type
  3. Define methods using MCP decorators, where:
  • Description is the question you will ask the LLM.

  • MethodName is what the LLM will call. Each capital letter will appear as a space in the LLM interface.

    • Example: GetTankLevel will appear as "Get Tank Level".

  • ParametersDescription explains what is expected for each parameter.

  • Parameters define the inputs.

  • Content defines the behavior or response of the method.

  • Result is what the LLM will receive in order to generate the answer, which it will then convert into a more human-readable response.

Code Block
languagec#
[McpServerTool, Description("<Description>")]
public string <MethodName>(
[Description("<ParametersDescription>")] <Parameters>)
{
	<Content>
    return <Result>;
}

Example:

Code Block
languagec#
[McpServerTool, Description("Get current tank level")]
public string GetTankLevel(
[Description("Tank identifier")] string tankId = "4")
{
    return @Tag.Tank_{tankId}_Level"].ToString();
}


Warning

After every configuration change or after shutting down and restarting the solution, you must fully restart the Desktop LLM. This means not only closing the application window, but also terminating the process (either from the system tray icon or via the Task Manager). This is a requirement of the LLM.

Additional Information

Error Handling

Within the custom methods, you can also add safeguards to help identify potential errors, as shown below:

Code Block
languagec#
[McpServerTool, Description("Safe data retrieval")]
public string GetData(string tagName)
{
    try
    {
        if (!@Tag.Exists(tagName))
            return $"Error: Tag {tagName} not found";
        
        return @Tag[tagName].ToString();
    }
    catch (Exception ex)
    {
        @Info.Trace($"MCP Error: {ex.Message}");
        return "Error: Unable to retrieve data";
    }
}

Troubleshooting

MCP Server not starting

  • Verify .NET 8.0 runtime installation
  • Check firewall settings for configured port
  • Confirm TMCPServerStdio.exe path is correct

AI cannot access methods

  • Ensure MCP decorators are properly applied
  • Verify solution is running (Runtime → Startup)
  • Check AI client configuration matches server settings
  • Verify is .NET 8.0 is installed in your computer
  • Restart your LLM completely (close in the Windows task Manager) after run the solution.

Data not updating

  • Confirm tags are properly configured
  • Verify real-time database connectivity
  • Check MCP method error handling

Getting Started

Quick Start Tutorial

Build your first MCP Tool and connect it to Claude AI:

AI MCP Tool Tutorial - Step-by-step guide for creating and deploying MCP Tools

Example Implementation

Explore a complete working example with MQTT integration:

SolarPanels MCP Demo - Full solution demonstrating MCP Tools with solar panel monitoring

Related Documentation



In this section...

Page Tree
root@parent