Meshtastic Plugin Authoring Guide

Installation & Setup

Note: Until the plugin system is officially accepted, you must use pip install followed by mpm init in the firmware folder to apply the plugin patches to the firmware. You'll need to do this to older versions of the firmware even if this is eventually accepted into core.

# Install MPM
pip install mesh-plugin-manager

# From the firmware folder (directory containing platformio.ini)
mpm init

The build system automatically uses MPM during PlatformIO builds to include all plugins and generate protobuf bindings.

Plugin Structure

The only requirement for a plugin is that it must have a ./src directory:

plugins/
└── myplugin/
    └── src/
        ├── MyModule.h
        ├── MyModule.cpp
        └── mymodule.proto
  • Plugin directory name can be anything
  • All source files must be placed in ./src
  • Only files in ./src are compiled (the root plugin directory and all other subdirectories are excluded from the build)

Automatic Protobuf Generation

MPM automatically scans for and generates protobuf files:

  • Discovery: Recursively scans plugin directories for .proto files
  • Options file: Auto-detects matching .options files (e.g., mymodule.protomymodule.options)
  • Generation: Uses nanopb tooling to generate C++ files
  • Output: Generated files are placed in the same directory as the .proto file
  • Timing: Runs during PlatformIO pre-build phase (configured in platformio.ini)

Example protobuf structure:

src/plugins/myplugin/src/
├── mymodule.proto      # Protobuf definition
├── mymodule.options    # Nanopb options (optional)
├── mymodule.pb.h       # Generated header
└── mymodule.pb.c       # Generated implementation

Include Path Setup

The plugin's src/ directory is automatically added to the compiler's include path (CPPPATH) during build:

  • Headers in src/ can be included directly: #include "MyModule.h"
  • No need to specify relative paths from other plugin files
  • The build system handles this automatically

Module Registration

If your plugin implements a Meshtastic module, use the #pragma MPM_MODULE directive in your header file:

  1. Add #pragma MPM_MODULE(ClassName) to your module's header file (.h)
  2. Optionally specify a variable name: #pragma MPM_MODULE(ClassName, variableName)
  3. If you specify a variable name, declare it as extern in your header file
  4. Your module will be automatically initialized when the firmware starts

Example (without variable):

// MyModule.h
#pragma once
#pragma MPM_MODULE(MyModule)

class MyModule : public SinglePortModule {
    // ... module definition ...
};

Example (with variable - for modules that need to be referenced elsewhere):

// MyModule.h
#pragma once
#pragma MPM_MODULE(MyModule, myModule)

#include "SinglePortModule.h"

class MyModule : public SinglePortModule {
    // ... module definition ...
};

// Declare the variable as extern so other files can reference it
extern MyModule *myModule;

The variable will be assigned in the generated init_dynamic_modules() function. If you don't need to reference your module from other files, you can omit the variable name and extern declaration.

Note: Module registration is optional. Plugins that don't implement Meshtastic modules (e.g., utility libraries) don't need this.

For details on writing Meshtastic modules, see the Module API documentation.

Example Plugins

  • LoBBS - an on-firmware BBS
  • LoDB - a microncontroller-friendly relational database for persisting settings, data, and more
  • See https://meshforge.org for more