Sign inSign up

tommi2day/symcon-mcp-server

By tommi2day

โ€ขUpdated 2 months ago

Connects AI assistants to IP-Symcon via the Model Context Protocol (MCP).

Image
Integration & delivery
Machine learning & AI
Data science
0

1.8K

tommi2day/symcon-mcp-server repository overview

Deutsche Version des READMEโ 

โ Symcon MCP Server ๐Ÿ 

Connects AI assistants to IP-Symconโ  via the Model Context Protocol (MCP).

CI codecov GitHub release Docker Image

Exposes the Symcon JSON-RPC API as MCP tools so that AI assistants (Claude, Cursor, VS Code Copilot, โ€ฆ) can read and control your smart home.

Important

The Symcon JSON-RPC API **requires authentication**. You must provide both `SYMCON_API_USER` (your license email) and `SYMCON_API_PASSWORD`.

โ Overview

ModeTransportWhen to use
Local (Node.js)stdioDevelopment, no Docker
Docker / RemoteHTTP or HTTPSDifferent host on the network

โ Environment Variables

VariableDefaultDescription
MCP_PORT4096Port the server listens on
MCP_HOST_PORT4096Docker host port
MCP_TRANSPORTstreamablestreamable, sse, or stdio
MCP_AUTH_TOKEN(empty)Bearer token; How to create?โ 
LOG_LEVELinfodebug, info, warn, error
SYMCON_API_URLhttp://host.docker.internal:3777/api/Symcon JSON-RPC endpointโ 
SYMCON_API_USER(empty)Symcon license username (required)
SYMCON_API_PASSWORD(empty)Symcon password (required)
SYMCON_TLS_VERIFYtrueSet false for self-signed certs

โ Docker Hub

The image is available on Docker Hub:

docker pull tommi2day/symcon-mcp-server:latest
โ Quick start from Hub (HTTP)
docker run -d --name symcon-mcp-server \
  -p 4096:4096 \
  -e SYMCON_API_URL=http://192.168.1.100:3777/api/ \
  -e [email protected] \
  -e SYMCON_API_PASSWORD=your-symcon-password \
  -e MCP_AUTH_TOKEN=my-secret-token \
  tommi2day/symcon-mcp-server:latest
โ In docker-compose.yml
services:
  symcon-mcp-server:
    image: tommi2day/symcon-mcp-server:latest
    ports:
      - "4096:4096"
    environment:
      - SYMCON_API_URL=http://192.168.1.100:3777/api/
      - [email protected]
      - SYMCON_API_PASSWORD=your-symcon-password
      - MCP_AUTH_TOKEN=my-secret-token

โ Token Authentication

When running the MCP server as an HTTP/SSE service, it's recommended to set a strong MCP_AUTH_TOKEN to prevent unauthorized access to your Symcon instance.

โ Automatic creation

If you use the provided ./scripts/run.sh to start the server, it will automatically generate a strong 32-byte hex token for you on the first run and save it to a file named auth_token in the project root.

โ Manual creation

You can generate a secure token manually using openssl (available on Linux, macOS, and Git Bash for Windows):

openssl rand -hex 32

Then, set this value as the MCP_AUTH_TOKEN environment variable in your .env file or docker run command.

โ Usage

When authentication is enabled, all requests to the MCP server must include the following header:

Authorization: Bearer <your-mcp-auth-token>

โ 1 ยท Local (stdio)

Set MCP_TRANSPORT=stdio and run via Node.js or Docker.

โ Claude Desktop (claude_desktop_config.json)
{
  "mcpServers": {
    "symcon": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "tommi2day/symcon-mcp-server"],
      "env": {
        "MCP_TRANSPORT": "stdio",
        "SYMCON_API_URL": "http://192.168.1.100:3777/api/",
        "SYMCON_API_USER": "[email protected]",
        "SYMCON_API_PASSWORD": "your-symcon-password"
      }
    }
  }
}

โ 2 ยท Docker (HTTP/SSE)

This mode runs the MCP server as a standalone container, exposing an HTTP endpoint for any compatible client.

โ Run with Docker

If you have a Symcon instance running elsewhere, run just the MCP server:

docker run -d --name symcon-mcp-server \
  -p 4096:4096 \
  -e SYMCON_API_URL=http://192.168.1.100:3777/api/ \
  -e [email protected] \
  -e SYMCON_API_PASSWORD=your-symcon-password \
  -e MCP_AUTH_TOKEN=my-secret-token \
  tommi2day/symcon-mcp-server:latest
โ Access with mcp.json

To use the server from an MCP client (like Cursor or VS Code), add it to your mcp.json configuration:

{
  "mcpServers": {
    "symcon": {
      "url": "http://localhost:4096/mcp",
      "headers": {
        "Authorization": "Bearer my-secret-token"
      }
    }
  }
}
โ Claude Desktop (claude_desktop_config.json) โ€” HTTP/Remote

Warning

**Claude Desktop only supports HTTPS for non-local (remote) MCP servers.** If your server runs on plain HTTP and is not on `localhost`, Claude Desktop will refuse the connection. Use one of the options below:

Option A โ€” Preferred: Put the server behind a reverse proxy (Traefik, nginx, Caddy) with a valid TLS certificate and use https:// in the URL.

Option B โ€” Quick workaround: Use mcp-remoteโ  as a local stdio bridge. It runs on your machine and forwards requests to the HTTP server, so Claude Desktop treats it like a stdio tool.

{
  "mcpServers": {
    "symcon": {
      "command": "npx",
      "args": [
        "-y", "mcp-remote",
        "http://192.168.1.100:4096/mcp",
        "--allow-http",
        "--header", "Authorization:Bearer my-secret-token"
      ]
    }
  }
}
โ Verify the MCP endpoint

Health check:

curl http://localhost:4096/health

MCP initialize handshake (checks that the server responds to MCP requests):

curl -s -X POST http://localhost:4096/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer my-secret-token" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'

Interactive browser UI via MCP Inspectorโ :

# Local server โ€” direct HTTP
npx @modelcontextprotocol/inspector http://localhost:4096/mcp

# Remote HTTP server โ€” via mcp-remote bridge
npx @modelcontextprotocol/inspector \
  npx mcp-remote http://192.168.1.100:4096/mcp \
  --allow-http \
  --header "Authorization:Bearer my-secret-token"

The inspector opens a browser UI where you can list tools, call them individually, and inspect responses.


โ 3 ยท Docker Compose (Full Stack)

Use this if you want to run both IP-Symcon and the MCP Server together in a single stack (e.g., for testing or evaluation).

  1. Clone and configure

    git clone https://github.com/tommi2day/symcon-mcp-server.git
    cd symcon-mcp-server
    cp .env.example .env
    

    Edit .env and set SYMCON_API_URL, SYMCON_API_USER, SYMCON_API_PASSWORD, and MCP_AUTH_TOKEN.

  2. Start

    # Starts both services
    docker compose up -d
    
  3. Verify

    curl http://localhost:4096/health
    
  4. Access Symcon GUI Open http://localhost:3777โ  in your browser to access the IP-Symcon console.


โ Architecture

AI Client (Claude / Cursor / โ€ฆ)
        โ”‚  HTTP POST /mcp
        โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   symcon-mcp-server     โ”‚  :4096
โ”‚   (Docker container)    โ”‚
โ”‚                         โ”‚
โ”‚  MCP Tools              โ”‚
โ”‚   โ”œโ”€ get_value          โ”‚
โ”‚   โ”œโ”€ set_value          โ”‚
โ”‚   โ”œโ”€ request_action     โ”‚
โ”‚   โ”œโ”€ get_variable       โ”‚
โ”‚   โ”œโ”€ get_object         โ”‚
โ”‚   โ”œโ”€ get_children       โ”‚
โ”‚   โ”œโ”€ get_object_by_name โ”‚
โ”‚   โ”œโ”€ get_variable_path  โ”‚
โ”‚   โ”œโ”€ snapshot_variables โ”‚
โ”‚   โ”œโ”€ diff_variables     โ”‚
โ”‚   โ”œโ”€ run_script         โ”‚
โ”‚   โ”œโ”€ run_script_text    โ”‚
โ”‚   โ”œโ”€ run_script_text_ex โ”‚
โ”‚   โ”œโ”€ get_script_content โ”‚
โ”‚   โ”œโ”€ script_create      โ”‚
โ”‚   โ”œโ”€ script_set_content โ”‚
โ”‚   โ””โ”€ script_delete      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
             โ”‚ [JSON-RPC](https://www.symcon.de/en/service/documentation/developer-area/data-exchange/)
             โ–ผ
    IP-Symcon  :3777/api/

โ Available MCP Tools

ToolDescription
symcon_get_valueRead the current value of a variable
symcon_set_valueWrite a value directly to a variable
symcon_request_actionTrigger a device action (use for real devices)
symcon_get_variableGet variable metadata (type, profile, timestamps)
symcon_get_objectGet metadata for any object (category, instance, โ€ฆ)
symcon_get_childrenList child object IDs (0 = root)
symcon_get_object_id_by_nameFind an object ID by name
symcon_get_variable_by_pathResolve a variable by slash-separated path
symcon_snapshot_variablesSnapshot all variable values under a root
symcon_diff_variablesDetect changes since a previous snapshot
symcon_run_scriptExecute an existing Symcon script by ID
symcon_run_script_textExecute arbitrary PHP code in Symcon
symcon_run_script_text_exExecute PHP and return structured output, return value, and errors as separate fields; output is byte-capped
symcon_get_script_contentRead the PHP source of an existing script (read-only, no execution)
symcon_script_createCreate a new PHP script in Symcon
symcon_script_set_contentUpdate an existing script's PHP content
symcon_script_deleteDelete a script by ID

โ Device Control Tips

โ Switches & relays
Use symcon_request_action with value true (on) or false (off)
โ Philips Hue brightness
Use symcon_request_action with value 0โ€“254 (0 = off, 254 = full brightness)
โ Finding your variable IDs

Ask the AI assistant:

"Find the object ID of my living room light"

โ Snapshot & Diff (device discovery)
  1. AI calls symcon_snapshot_variables on the relevant room
  2. AI asks: "Please toggle the device you want to assign, then tell me"
  3. User toggles the device
  4. AI calls symcon_diff_variables to identify which variable changed

โ Endpoints

EndpointMethodDescription
/GETServer info and available endpoints
/healthGETHealth check (Symcon status, uptime, version)
/infoGETDetailed server configuration and Symcon version
/mcpPOST/GET/DELETEMCP Streamable HTTP transport
/sseGETMCP SSE transport (if MCP_TRANSPORT=sse)
/messagesPOSTSSE message handler
StdioN/AMCP Stdio transport (if MCP_TRANSPORT=stdio)

โ Development & Testing

โ Running tests locally
# Install
npm install

# Unit tests
npm test

# Integration tests (starts a real Symcon Docker container)
npm run test:integration

# All tests
npm run test:all
โ Using Docker Scripts
./scripts/test.sh                     # unit tests via Docker
./scripts/test.sh --integration       # unit + integration tests
./scripts/lint.sh                     # lint
โ Test architecture
Test suiteFileDependencies
Unit: SymconClienttests/symcon-client.test.tsMockSymconServer (in-process)
Unit: MCP toolstests/tools.test.tsMockSymconServer + InMemoryTransport
Unit: HTTP servertests/http-server.test.tsMockSymconServer + spawned Express
Unit: Info endpointtests/info.test.tsMockSymconServer + spawned Express (auth, masking & Symcon version)
Integrationtests/integration.test.tsReal symcon/symcon-server Docker container

โ CI/CD

The repository uses two primary GitHub Actions workflows:

CI (ci.yml) โ€“ runs on every push and pull request:

  1. Lint: ESLint checks.
  2. Test: Unit tests on Node 24.
  3. Coverage: Unit test coverage calculation.
  4. Integration Tests: Runs integration tests against a real Symcon Docker service container.
  5. Report: Uploads coverage results to Codecov.

Release (release.yml) โ€“ triggered by a semver tag or manual dispatch:

  1. Bump version (Manual only): Updates package.json and openapi.yaml, commits and pushes to main.
  2. Lint & Test: Runs lint, unit tests with coverage, and integration tests.
  3. Build & Push: Multi-arch Docker build and push to Docker Hub (tommi2day/symcon-mcp-server).
  4. Create Release: Creates a GitHub tag (if manual) and a GitHub Release with auto-generated notes.

โ Production Checklist

  • Set a strong MCP_AUTH_TOKEN
  • Restrict port 4096 via firewall or only expose via reverse proxy
  • Use HTTPS via a reverse proxy (Traefik, nginx, Caddy) in production
  • Check /health from your monitoring system

โ License

MIT

Tag summary

Content type

Image

Digest

sha256:cd40e076dโ€ฆ

Size

65.7 MB

Last updated

2 months ago

docker pull tommi2day/symcon-mcp-server