This guide covers cloning, building, running, and debugging MeshAgent on your local machine.
# Clone the repository
git clone https://github.com/flamingo-stack/meshagent.git
cd meshagent
# Install JavaScript tooling dependencies
npm installThe repository contains no submodule initialization needed — OpenSSL headers and libjpeg-turbo headers are bundled directly in the source tree.
makeThis compiles all C sources from meshcore/, microstack/, and microscript/, links them with system OpenSSL and zlib, and produces the meshagent binary in the project root.
CFLAGS="-g -O0 -DDEBUG" make clean && makemake V=1makeEnsure Xcode Command Line Tools are installed:
xcode-select --installThe macOS build links against CoreGraphics and IOKit for KVM support.
When developing the KVM engine on macOS, the binary needs to be signed to use CoreGraphics and receive TCC permissions. For local development, an ad-hoc signature is sufficient:
codesign --force --sign - ./meshagentGrant Screen Recording and Accessibility permissions in System Settings → Privacy & Security to your signed binary.
Open a Developer Command Prompt for Visual Studio, then:
nmakeOr build via the Visual Studio IDE using the solution file if present. The Windows build includes:
meshconsole/— Console applicationmeshservice/— Windows Service hostmeshreset/— Reset utility- Windows KVM engine (GDI/DXGI, secure desktop)
- Windows cryptography (
wincrypto)
Create a meshagent.msh file for local development. Point it to a local or development management server:
MeshServer=wss://dev-server.local/agent.ashx
MeshID=your-dev-mesh-id
MeshType=2
./meshagentOn first run, the agent auto-generates meshagent.db (identity store). Subsequent runs reuse the stored identity.
The JavaScript logging layer defaults to INFO. To see all debug output, set the log level before running scripts:
const logger = require('./modules/logger');
logger.setLevel('DEBUG');For the native C layer, build with -DDEBUG to enable additional print statements from the Microstack and Meshcore subsystems.
For full end-to-end development, run a local MeshCentral server:
# Install MeshCentral (Node.js required)
npm install meshcentral
# Start MeshCentral
node node_modules/meshcentralMeshCentral listens on port 4430 (HTTPS) by default. After creating a mesh group in the web UI, copy the MeshServer URL and MeshID into your meshagent.msh.
MeshAgent is a compiled native binary — there is no hot-reload for C code. The standard development loop is:
# Edit C source files, then rebuild
make && ./meshagentmake only recompiles changed files (via dependency tracking in the Makefile). A typical incremental build after modifying a single .c file takes a few seconds.
JavaScript modules in modules/ are interpreted at runtime by the embedded Duktape engine. Changes to .js files take effect on the next agent restart — no recompile needed:
# Edit modules/logger.js, then restart the agent
./meshagentFor the CoreModule.js (the main agent JavaScript entrypoint), the agent loads and executes it fresh each time it reconnects to the server.
# Build with debug symbols
CFLAGS="-g -O0" make clean && make
# Run under GDB
gdb ./meshagent
(gdb) run
# On crash, print stack trace
(gdb) bt
# Set a breakpoint by function name
(gdb) break MeshAgent_Start
(gdb) runlldb ./meshagent
(lldb) run
(lldb) bt all
(lldb) breakpoint set --name kvm_relay_setupvalgrind --leak-check=full --track-origins=yes ./meshagentNote: Valgrind is slow. Use it for targeted memory safety investigations rather than routine runs.
Enable the JavaScript debugger by setting the port in the agent data store:
Add to meshagent.db or pass via configuration:
jsDebugPort=9090
The agent will listen on TCP port 9090 for a debugger connection. Connect with:
- The Duktape Debugger VS Code extension
- The
duk-debugcommand-line tool - Any Duktape debug protocol compatible client
After a successful build:
# Check the binary exists and is executable
ls -la meshagent
# Check what it was built against (Linux)
ldd meshagent
# Check binary architecture
file meshagent
# Check it starts without crashing (no .msh file = exits cleanly)
./meshagent --help 2>&1 || true| Issue | Cause | Fix |
|---|---|---|
ssl.h: No such file or directory |
Missing OpenSSL dev headers | Install libssl-dev (Debian) or openssl-devel (RPM) |
undefined reference to X11* |
Missing X11 dev headers | Install libx11-dev, libxtst-dev |
undefined reference to gzopen |
Missing zlib | Install zlib1g-dev |
codesign: error (macOS) |
Missing Xcode tools | Run xcode-select --install |
CC: command not found |
No C compiler | Install build-essential or Xcode |
For additional help, join the OpenMSP Slack.
meshagent/
├── meshcore/agentcore.h # MeshAgentHostContainer — the central agent state struct
├── meshcore/agentcore.c # Agent lifecycle: Create, Start, Stop, Destroy
├── meshcore/meshdefines.h # Protocol constants (port 16990, command opcodes)
├── microstack/ILibChain.* # Reactor event loop (ILibChain) — the async core
├── microstack/ILibWebRTC.* # WebRTC (ICE, DTLS, SCTP)
├── microscript/duktape.* # Duktape JavaScript engine
├── modules/CoreModule.js # Primary JavaScript entrypoint executed by the server
├── openframe/token_extractor.*# AES-256 token decryption for OpenFrame
└── package.json # Node.js tooling dependencies