Skip to content

Commit 006635e

Browse files
committed
updating server, adding more tools
1 parent 7884486 commit 006635e

35 files changed

+3709
-2448
lines changed

Dockerfile

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,36 @@
11
FROM python:3.12-slim
22
LABEL authors="Litmus Automation, Inc."
3+
LABEL description="Litmus MCP Server - SSE-based Model Context Protocol server for Litmus Edge"
34

4-
5+
# Install system dependencies
56
RUN apt-get update && apt-get install -y \
6-
build-essential curl \
7+
build-essential \
8+
curl \
79
&& rm -rf /var/lib/apt/lists/*
810

11+
# Install uv for fast package management
912
COPY --from=ghcr.io/astral-sh/uv:latest /uv /bin/uv
1013
COPY --from=ghcr.io/astral-sh/uv:latest /uvx /bin/uvx
14+
15+
# Set working directory
1116
WORKDIR /app
1217

13-
COPY . .
14-
RUN uv venv && uv sync --all-groups
18+
# Copy project files
19+
COPY pyproject.toml uv.lock ./
20+
COPY src ./src
21+
COPY run.sh ./
22+
23+
# Install dependencies using uv
24+
RUN uv venv && uv sync --frozen
1525

26+
# Activate virtual environment
1627
ENV PATH="/app/.venv/bin:$PATH"
1728

18-
#CMD python src/server.py --transport=sse & python src/webclient.py src/server.py && wait
29+
# Expose the MCP server port (default 8000)
30+
EXPOSE 8000
31+
32+
# Make run script executable
1933
RUN chmod +x run.sh
34+
35+
# Run the server
2036
CMD ["./run.sh"]

README.md

Lines changed: 124 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ The official [Litmus Automation](https://litmus.io) **Model Context Protocol (MC
3333
- [Getting Started](#getting-started)
3434
- [Quick Launch (Docker)](#quick-launch-docker)
3535
- [Cursor IDE Setup](#cursor-ide-setup)
36-
- [API](#api)
36+
- [Tools](#available-tools)
3737
- [Usage](#usage)
3838
- [Server-Sent Events (SSE)](#server-sent-events-sse)
3939
- [Litmus Central](#litmus-central)
@@ -52,7 +52,7 @@ The official [Litmus Automation](https://litmus.io) **Model Context Protocol (MC
5252
Run the server in Docker:
5353

5454
```bash
55-
docker run -d --name litmus-mcp-server -p 8000:8000 ghcr.io/litmusautomation/litmus-mcp-server:main
55+
docker run -d --name litmus-mcp-server -p 8000:8000 ghcr.io/litmusautomation/litmus-mcp-server:latest
5656
```
5757

5858
### Cursor IDE Setup
@@ -63,36 +63,79 @@ Example `mcp.json` configuration:
6363
{
6464
"mcpServers": {
6565
"litmus-mcp-server": {
66-
"url": "http://<IP Address>:8000/sse"
66+
"url": "http://<MCP_SERVER_IP>:8000/sse",
67+
"headers": {
68+
"EDGE_URL": "https://<LITMUSEDGE_IP>",
69+
"EDGE_API_CLIENT_ID": "<oauth2_client_id>",
70+
"EDGE_API_CLIENT_SECRET": "<oauth2_client_secret>",
71+
72+
"NATS_SOURCE": "<LITMUSEDGE_IP>",
73+
"NATS_PORT": "4222",
74+
"NATS_USER": "<access_token_username>",
75+
"NATS_PASSWORD": "<access_token_from_litmusedge>",
76+
77+
"INFLUX_HOST": "<LITMUSEDGE_IP>",
78+
"INFLUX_PORT": "8086",
79+
"INFLUX_DB_NAME": "tsdata",
80+
"INFLUX_USERNAME": "<datahub_username>",
81+
"INFLUX_PASSWORD": "<datahub_password>"
82+
}
6783
}
6884
}
6985
}
7086
```
7187

88+
**Header Configuration Guide:**
89+
- `EDGE_URL`: Litmus Edge base URL (include https://)
90+
- `EDGE_API_CLIENT_ID` / `EDGE_API_CLIENT_SECRET`: OAuth2 credentials from Litmus Edge
91+
- `NATS_SOURCE`: Litmus Edge IP (no http/https)
92+
- `NATS_USER` / `NATS_PASSWORD`: Access token credentials from **System → Access Control → Tokens**
93+
- `INFLUX_HOST`: Litmus Edge IP (no http/https)
94+
- `INFLUX_USERNAME` / `INFLUX_PASSWORD`: DataHub user credentials
95+
7296
See the [Cursor docs](https://docs.cursor.com/context/model-context-protocol) for more info.
7397

7498
---
7599

76-
## API
100+
## Available Tools
77101

78102
| Category | Function Name | Description |
79103
|---------------------------|----------------------------------------|-------------|
80-
| **Edge System Config** | `get_current_environment_config` | Get current environment configuration used for Litmus Edge connectivity. |
81-
| | `update_environment_config` | Update environment variable config for connecting to Litmus Edge. |
82-
| | `get_current_config` | Retrieve current Litmus Edge instance configuration. |
83-
| | `update_config` | Update configuration of the device or container running Litmus Edge. |
84-
| **DeviceHub** | `get_litmusedge_driver_list` | List supported Litmus Edge drivers. |
85-
| | `get_devicehub_devices` | List devices configured in DeviceHub. |
86-
| | `get_devicehub_device_tags` | Retrieve tags for a specific DeviceHub device. |
87-
| | `get_current_value_of_devicehub_tag` | Get current value of a specific device tag. |
88-
| | `create_devicehub_device` | Register a new DeviceHub device. Supports various protocols and templates for register-based data polling. |
89-
| **Device Identity** | `get_litmusedge_friendly_name` | Retrieve the user-friendly name of the device. |
90-
| | `set_litmusedge_friendly_name` | Assign or update the friendly name. |
91-
| **LEM Integration** | `get_cloud_activation_status` | Check cloud activation and Litmus Edge Manager (LEM) connection status. |
92-
| **Docker Management** | `get_all_containers_on_litmusedge` | List all containers on Litmus Edge. |
93-
| | `run_docker_container_on_litmusedge` | Launch a Docker container via Litmus Edge Marketplace (not the MCP host). |
94-
| **Topic Subscription** | `get_current_value_on_topic` | Subscribe to current values on a Litmus Edge topic. Use global `NATS_STATUS = False` to unsubscribe. |
95-
| | `get_multiple_values_from_topic` | Retrieve multiple values from a topic for plotting or batch access. |
104+
| **DeviceHub** | `get_litmusedge_driver_list` | List supported Litmus Edge drivers (e.g., ModbusTCP, OPCUA, BACnet). |
105+
| | `get_devicehub_devices` | List all configured DeviceHub devices with connection settings and status. |
106+
| | `create_devicehub_device` | Create a new device with specified driver and default configuration. |
107+
| | `get_devicehub_device_tags` | Retrieve all tags (data points/registers) for a specific device. |
108+
| | `get_current_value_of_devicehub_tag` | Read the current real-time value of a specific device tag. |
109+
| **Device Identity** | `get_litmusedge_friendly_name` | Get the human-readable name assigned to the Litmus Edge device. |
110+
| | `set_litmusedge_friendly_name` | Update the friendly name of the Litmus Edge device. |
111+
| **LEM Integration** | `get_cloud_activation_status` | Check cloud registration and Litmus Edge Manager (LEM) connection status. |
112+
| **Docker Management** | `get_all_containers_on_litmusedge` | List all Docker containers running on Litmus Edge Marketplace. |
113+
| | `run_docker_container_on_litmusedge` | Deploy and run a new Docker container on Litmus Edge Marketplace. |
114+
| **NATS Topics** * | `get_current_value_from_topic` | Subscribe to a NATS topic and return the next published message. |
115+
| | `get_multiple_values_from_topic` | Collect multiple sequential values from a NATS topic for trend analysis. |
116+
| **InfluxDB** ** | `get_historical_data_from_influxdb` | Query historical time-series data from InfluxDB by measurement and time range. |
117+
| **Digital Twins** | `list_digital_twin_models` | List all Digital Twin models with ID, name, description, and version. |
118+
| | `list_digital_twin_instances` | List all Digital Twin instances or filter by model ID. |
119+
| | `create_digital_twin_instance` | Create a new Digital Twin instance from an existing model. |
120+
| | `list_static_attributes` | List static attributes (fixed key-value pairs) for a model or instance. |
121+
| | `list_dynamic_attributes` | List dynamic attributes (real-time data points) for a model or instance. |
122+
| | `list_transformations` | List data transformation rules configured for a Digital Twin model. |
123+
| | `get_digital_twin_hierarchy` | Get the hierarchy configuration for a Digital Twin model. |
124+
| | `save_digital_twin_hierarchy` | Save a new hierarchy configuration to a Digital Twin model. |
125+
126+
### Configuration Notes
127+
128+
**\* NATS Topic Tools Requirements:**
129+
To use `get_current_value_from_topic` and `get_multiple_values_from_topic`, you must configure access control on Litmus Edge:
130+
1. Navigate to: **Litmus Edge → System → Access Control → Tokens**
131+
2. Create or configure an access token with appropriate permissions
132+
3. Provide the token in your MCP client configuration headers
133+
134+
**\*\* InfluxDB Tools Requirements:**
135+
To use `get_historical_data_from_influxdb`, you must allow InfluxDB port access:
136+
1. Navigate to: **Litmus Edge → System → Network → Firewall**
137+
2. Add a firewall rule to allow port **8086** on **TCP**
138+
3. Ensure InfluxDB is accessible from the MCP server host
96139

97140
---
98141

@@ -126,7 +169,21 @@ Add to `~/.cursor/mcp.json` or `.cursor/mcp.json`:
126169
{
127170
"mcpServers": {
128171
"litmus-mcp-server": {
129-
"url": "http://<IP Address>:8000/sse"
172+
"url": "http://<MCP_SERVER_IP>:8000/sse",
173+
"headers": {
174+
"EDGE_URL": "https://<LITMUSEDGE_IP>",
175+
"EDGE_API_CLIENT_ID": "<oauth2_client_id>",
176+
"EDGE_API_CLIENT_SECRET": "<oauth2_client_secret>",
177+
"NATS_SOURCE": "<LITMUSEDGE_IP>",
178+
"NATS_PORT": "4222",
179+
"NATS_USER": "<access_token_username>",
180+
"NATS_PASSWORD": "<access_token_from_litmusedge>",
181+
"INFLUX_HOST": "<LITMUSEDGE_IP>",
182+
"INFLUX_PORT": "8086",
183+
"INFLUX_DB_NAME": "tsdata",
184+
"INFLUX_USERNAME": "<datahub_username>",
185+
"INFLUX_PASSWORD": "<datahub_password>"
186+
}
130187
}
131188
}
132189
}
@@ -144,7 +201,21 @@ Add to `claude_desktop_config.json`:
144201
{
145202
"mcpServers": {
146203
"litmus-mcp-server": {
147-
"url": "http://<IP Address>:8000/sse"
204+
"url": "http://<MCP_SERVER_IP>:8000/sse",
205+
"headers": {
206+
"EDGE_URL": "https://<LITMUSEDGE_IP>",
207+
"EDGE_API_CLIENT_ID": "<oauth2_client_id>",
208+
"EDGE_API_CLIENT_SECRET": "<oauth2_client_secret>",
209+
"NATS_SOURCE": "<LITMUSEDGE_IP>",
210+
"NATS_PORT": "4222",
211+
"NATS_USER": "<access_token_username>",
212+
"NATS_PASSWORD": "<access_token_from_litmusedge>",
213+
"INFLUX_HOST": "<LITMUSEDGE_IP>",
214+
"INFLUX_PORT": "8086",
215+
"INFLUX_DB_NAME": "tsdata",
216+
"INFLUX_USERNAME": "<datahub_username>",
217+
"INFLUX_PASSWORD": "<datahub_password>"
218+
}
148219
}
149220
}
150221
}
@@ -158,14 +229,28 @@ Add to `claude_desktop_config.json`:
158229

159230
#### Manual Configuration
160231

161-
In VS Code:
232+
In VS Code:
162233
Open User Settings (JSON) → Add:
163234

164235
```json
165236
{
166237
"mcpServers": {
167238
"litmus-mcp-server": {
168-
"url": "http://<IP Address>:8000/sse"
239+
"url": "http://<MCP_SERVER_IP>:8000/sse",
240+
"headers": {
241+
"EDGE_URL": "https://<LITMUSEDGE_IP>",
242+
"EDGE_API_CLIENT_ID": "<oauth2_client_id>",
243+
"EDGE_API_CLIENT_SECRET": "<oauth2_client_secret>",
244+
"NATS_SOURCE": "<LITMUSEDGE_IP>",
245+
"NATS_PORT": "4222",
246+
"NATS_USER": "<access_token_username>",
247+
"NATS_PASSWORD": "<access_token_from_litmusedge>",
248+
"INFLUX_HOST": "<LITMUSEDGE_IP>",
249+
"INFLUX_PORT": "8086",
250+
"INFLUX_DB_NAME": "tsdata",
251+
"INFLUX_USERNAME": "<datahub_username>",
252+
"INFLUX_PASSWORD": "<datahub_password>"
253+
}
169254
}
170255
}
171256
}
@@ -185,7 +270,21 @@ Add to `~/.codeium/windsurf/mcp_config.json`:
185270
{
186271
"mcpServers": {
187272
"litmus-mcp-server": {
188-
"url": "http://<IP Address>:8000/sse"
273+
"url": "http://<MCP_SERVER_IP>:8000/sse",
274+
"headers": {
275+
"EDGE_URL": "https://<LITMUSEDGE_IP>",
276+
"EDGE_API_CLIENT_ID": "<oauth2_client_id>",
277+
"EDGE_API_CLIENT_SECRET": "<oauth2_client_secret>",
278+
"NATS_SOURCE": "<LITMUSEDGE_IP>",
279+
"NATS_PORT": "4222",
280+
"NATS_USER": "<access_token_username>",
281+
"NATS_PASSWORD": "<access_token_from_litmusedge>",
282+
"INFLUX_HOST": "<LITMUSEDGE_IP>",
283+
"INFLUX_PORT": "8086",
284+
"INFLUX_DB_NAME": "tsdata",
285+
"INFLUX_USERNAME": "<datahub_username>",
286+
"INFLUX_PASSWORD": "<datahub_password>"
287+
}
189288
}
190289
}
191290
}

pyproject.toml

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
[project]
22
name = "litmus-mcp-server"
33
version = "0.1.0"
4-
description = "Litmus MCP Server and client combo"
4+
description = "Litmus MCP Server"
55
readme = "README.md"
66
requires-python = ">=3.12"
77
dependencies = [
8-
"fastapi>=0.115.12",
9-
"jinja2>=3.1.6",
8+
"influxdb>=5.3.2",
109
"litmussdk",
11-
"mcp[cli]>=1.8.0",
12-
"nats-py>=2.10.0",
13-
"numpy>=2.2.5",
10+
"mcp[cli]>=1.17.0",
11+
"nats-py>=2.11.0",
12+
"numpy>=2.3.4",
13+
"pandas>=2.3.3",
1414
"python-multipart>=0.0.20",
1515
]
1616

@@ -19,18 +19,17 @@ cve-patches = [
1919
"h11>=0.16.0",
2020
]
2121
lint = [
22-
"black>=25.1.0",
22+
"black>=25.9.0",
2323
"radon>=6.0.1",
24-
"ruff>=0.11.4",
24+
"ruff>=0.14.0",
2525
]
26-
llm-sdks = [
27-
"anthropic>=0.49.0",
28-
"openai-agents>=0.0.13",
29-
]
30-
test = []
26+
test = [
27+
"pytest>=8.4.2",
28+
]
29+
3130

3231
[tool.uv.sources]
33-
litmussdk = { url = "https://github.com/litmusautomation/litmus-sdk-releases/releases/download/1.0.0/litmussdk-1.0.0-py3-none-any.whl" }
32+
litmussdk = { url = "https://github.com/litmusautomation/litmus-sdk-releases/releases/download/1.1.1/litmussdk-1.1.1-py3-none-any.whl" }
3433

3534
[tool.ruff]
3635
exclude = [

run.sh

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,6 @@
11
#!/bin/bash
22
set -e
33

4-
# Start server
5-
mcp run src/server.py --transport=sse &
6-
SERVER_PID=$!
7-
8-
# Start web client
9-
python src/web_client.py src/server.py &
10-
CLIENT_PID=$!
11-
12-
# Wait for both
13-
wait $SERVER_PID $CLIENT_PID
4+
# Start the MCP server directly with Python
5+
# The server uses uvicorn internally and runs on port 8000 by default
6+
python src/server.py

src/cli_client.py

Lines changed: 0 additions & 24 deletions
This file was deleted.

0 commit comments

Comments
 (0)