Skip to main content

An MCP server for basic MQTT operations

Project description

MCP MQTT Server

An MCP (Model Context Protocol) server that provides MQTT operations to LLM agent pipelines through a discoverable interface. The server supports fine-grained topic permissions with wildcard matching and provides comprehensive MQTT functionality for MCP clients.

The MCP MQTT server allows operation in stdio mode as well as HTTP streamable remote operation via Unix domain sockets (recommended) or TCP/IP.

Installation

pip install mcpMQTT

To run the remote HTTP/UDS server, install the optional FastAPI/uvicorn extras:

pip install "mcpMQTT[remote]"

Configuration

Configuration File Structure

Create a configuration file at ~/.config/mcpmqtt/config.json or specify a custom path when launching the utility on the command line using the --config parameter:

{
  "mqtt": {
    "host": "localhost",
    "port": 1883,
    "username": null,
    "password": null,
    "keepalive": 60
  },
  "topics": [
    {
      "pattern": "sensors/+/temperature",
      "permissions": ["read"],
      "description": "Temperature sensor data from any location (+ matches single level like 'room1', 'room2'. Known rooms are 'exampleroom1' and 'exampleroom2'). Use subscribe, not read on this topic. Never publish."
    },
    {
      "pattern": "sensors/+/humidity",
      "permissions": ["read"],
      "description": "Humidity sensor data from any location. (+ matches single level like 'room1', 'room2'. Known rooms are 'exampleroom1' and 'exampleroom2'). Use subscribe, not read on this topic. Never publish. Data returned as %RH"
    },
    {
      "pattern": "actuators/#",
      "permissions": ["write"],
      "description": "All actuator control topics (# matches multiple levels like 'lights/room1'. To enable a light you write any payload to 'lights/room1/on', to disable you write to 'lights/room1/off')"
    },
    {
      "pattern": "status/system",
      "permissions": ["read"],
      "description": "System status information - exact topic match"
    },
    {
      "pattern": "commands/+/request",
      "permissions": ["write"],
      "description": "Command request topics for request/response patterns"
    },
    {
      "pattern": "commands/+/response",
      "permissions": ["read"],
      "description": "Command response topics for request/response patterns"
    }
  ],
  "logging": {
    "level": "INFO",
    "logfile": null
  },
  "remote_server": {
    "api_key_kdf": {
      "algorithm": "argon2id",
      "salt": "<base64-salt>",
      "time_cost": 3,
      "memory_cost": 65536,
      "parallelism": 1,
      "hash_len": 32,
      "hash": "<base64-hash>"
    },
    "uds": "/var/run/mcpmqtt.sock",
    "host": "0.0.0.0",
    "port": null
  }
}

Use mcpMQTT --genkey to populate the api_key_kdf block. The command prints the new API key exactly once to stdout so you can copy it into your secrets manager.

Configuration Sections

  • mqtt: MQTT broker connection settings
  • topics: Topic patterns with permissions and descriptions
  • logging: Application logging level
  • remote_server (optional when using stdio transport): Remote FastAPI settings, including the KDF protected API key (api_key_kdf) and the bind configuration. Leaving port as null keeps the Unix domain socket default (/var/run/mcpmqtt.sock). Setting a TCP port automatically switches to TCP mode and host defaults to 0.0.0.0 if omitted. The legacy plaintext api_key field still loads but should be replaced with the hashed format via --genkey.

Remote Server Settings

  • Authentication: The API key must accompany every MCP call via Authorization: Bearer <key>, X-API-Key: <key>, or ?api_key=<key>. The /status endpoint intentionally skips authentication so external health probes can call it.
  • Binding: Unix domain sockets are used by default (/var/run/mcpmqtt.sock). Provide a TCP port (and optionally host) to listen on TCP instead; the host defaults to all interfaces.
  • Mount path: The FastMCP Starlette application is mounted at /mcp
  • Status endpoint: GET /status returns { "running": true, "mqtt_connected": <bool> }, exposing reachability and MQTT connectivity.
  • Dependencies: Install FastAPI/uvicorn extras when using remote mode: pip install "mcpMQTT[remote]".

Topic Patterns and Permissions

Wildcard Support:

  • +: Single-level wildcard (matches one topic level)
  • #: Multi-level wildcard (matches multiple levels, must be last)

Permissions:

  • read: Can subscribe to topics and receive messages
  • write: Can publish messages to topics
  • Both permissions can be combined: ["read", "write"]

Examples:

  • sensors/+/temperature matches sensors/room1/temperature, sensors/kitchen/temperature
  • actuators/# matches actuators/lights, actuators/lights/room1/brightness
  • status/system matches exactly status/system

Usage

Running the MCP Server

Using the installed script:

mcpMQTT

Remote HTTP/UDS mode:

mcpMQTT --transport remotehttp

With custom configuration:

mcpMQTT --config /path/to/config.json --log-level DEBUG

Generate a new remote API key (prints to STDOUT once):

mcpMQTT --config /path/to/config.json --genkey

MCP Tools

The MCP server provides three tools for MQTT operations:

mqtt_publish

Publish messages to MQTT topics.

{
  "topic": "sensors/room1/temperature",
  "payload": "22.5",
  "qos": 0
}

mqtt_subscribe

Subscribe to topics and collect messages.

{
  "topic": "sensors/+/temperature",
  "timeout": 30,
  "max_messages": 5
}

mqtt_read

Subscribe to a topic and wait for a single message.

{
  "topic" : "sensors/+/temperature",
  "timeout" : 5
}

mqtt_query

Request/response pattern for MQTT communication.

{
  "request_topic": "commands/room1/request",
  "response_topic": "commands/room1/response",
  "payload": "get_status",
  "timeout": 5
}

MCP Resources

mcpmqtt://topics/allowed

Get allowed topic patterns with permissions and descriptions.

mcpmqtt://topics/examples

Get examples of how to use topic patterns with wildcards.

Configuration Examples

For detailed configuration examples, see the examples/ folder:

Examples

MCP Client Integration

This MCP server uses the stdio protocol. This means that it should be launched by your LLM orchestrator.

A typical configuration (mcp.json) may look like the following:

{
  "mcpServers": {
    "mqtt": {
      "command": "mcpMQTT",
      "args": [
        "--config /usr/local/etc/mcpMQTT.conf"
      ],
      "env": {
        "PYTHONPATH": "/just/an/example/path/"
      },
      "timeout": 300,
      "alwaysAllow": [
        "mqtt_read"
      ]
    }
  }
}

Security Considerations

Keep in mind that this MCP allows an agent to subscribe to and publish to all topics that are exposed to the user associated with him on the MQTT broker. You have to perform fine grained configuration on your MQTT broker to limit which features the MCP can actually access or manipulate.

License

See LICENSE.md

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mcpmqtt-0.0.4.tar.gz (19.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mcpmqtt-0.0.4-py3-none-any.whl (19.6 kB view details)

Uploaded Python 3

File details

Details for the file mcpmqtt-0.0.4.tar.gz.

File metadata

  • Download URL: mcpmqtt-0.0.4.tar.gz
  • Upload date:
  • Size: 19.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.11.11

File hashes

Hashes for mcpmqtt-0.0.4.tar.gz
Algorithm Hash digest
SHA256 91a96224f306e2ce6a5dbe0d7134e98bc3b9a5868663f2aa50d6b8e30dfd4d75
MD5 fb6d28a16d7ce8f3de6b219504f44eae
BLAKE2b-256 b222340cc9cff8aa706931feb8592d0f6a5e1733b86ed0ece9707555fb21f84d

See more details on using hashes here.

File details

Details for the file mcpmqtt-0.0.4-py3-none-any.whl.

File metadata

  • Download URL: mcpmqtt-0.0.4-py3-none-any.whl
  • Upload date:
  • Size: 19.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.11.11

File hashes

Hashes for mcpmqtt-0.0.4-py3-none-any.whl
Algorithm Hash digest
SHA256 f9b0c193bb18fbd4229d983728c415578caf3ee9b517abe58c230a1c9dcc95a4
MD5 ece9e359eaa8062545db5a0150dabec3
BLAKE2b-256 c297b7e1a13b5986b054ead2eb7a07a6a1acf9b8c9a216e992f4786e4b574b94

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page