No Python Needed CLI (unofficial)

Hey everyone!

I made a post not too long ago about releasing a Go API that anyone can use to interact with meshtastic radios. My ultimate goal in making this was to create a new CLI that would work without any dependencies (like Python) to help when running tests on the radios. The only thing that’s needed to get it up and running is to download the appropriate executable, make sure the drivers are installed (Mac OS and Windows) and execute the command! It’s not quite at feature parity with the Python CLI, but I think the most important components are all available. I’ve tested it on Mac OS (Big Sur), Windows 10 and Raspberry Pi OS without any issues.

The repository for the tool is here on Github with the latest executables available for download here. Feel free to kick the tires and let me know if there are any problems!


Some thoughts:

  • Would be nice to have binaries for x86, x86_64 on Linux, too. ( nevermind, it’s being EOL’d as of this week.)
  • Meshtastic control protocol over TCP/IP support would be nice; the Python API implements this under TCPInterface.
1 Like

Thanks for the feedback! It’s pretty easy to add more supported systems to the releases. If you’d like to have an executable for any system in particular let me know and I can add them to the current version!

The TCP connection is next on my list of upgrades, I’ve just been cleaning up some bugs with this version before starting new development.


on OSX


I have tried double clicking and running from terminal with

what is the correct way to run this ?

In the end I grabbed the source and built it myself
the self built go version works
no idea about the pre-built one

You may need to make sure it has execute permissions by running chmod +x meshtastic_go_osx. After this the command should work by running

meshtastic_go_osx -p <port> info

Where is the serial port

yes, +x was the fix
not set on the pre-built version

1 Like

I’d find an x86 Linux version more valuable, but since my node is hanging from a window, I’d prioritize the TCP transport first. I’m not particularly keen on taking it down from my window to plug it into my PC. :slight_smile:

I don’t blame you on not wanting to take it down from a window :laughing:. I have a new release out here that includes TCP communications. All you need to do is the pass the IP of the radio in the --port flag and it will communicate with it over TCP. If you try it out feel free to let me know if you run into any issues!

1 Like

So I tried it out on my Windows laptop – I see you’ve added Linux x86_64 as a supported target. Any chance you’d be willing to add a Linux x86 (32-bit), too?

Some feedback:

  • It appears TCP is used for the transport if --port is given an IP address. It would be good to support hostnames (and ports? --address hostname:port|--address hostname|--port devicename) as well; the Meshtastic firmware advertises a hostname (i.e. through the ESP-IDF DHCP client), which many wireless gateway firmwares respect. Of course, if the option --port is shared between (arbitrarily named) local serial ports and (arbitrarily named) TCP/IP hosts, you can end up with some interesting behavior (say, hostname of ttyUSB2, or a symlink to a serial port named; it’s probably better to make the transport an explicit choice.
  • The message recv command doesn’t behave the way I’d expect them to, based on the help messages. It looks like the message recv command requires the --exit ‘option’; without it, the command prints the help message. However, the --help message indicates that -e / --exit defaults to false; the behavior of message recv --exit false (waits for a message) differs from message recv (prints help message).
  • The --help switch (on all the commands?) says that its default is “false” (?), but setting it to true or false doesn’t change anything – the help message is always displayed. I’m guessing this is an oddity of whatever library you’re using for parsing the command line.
  • The info command seems to be much slower than the equivalent in the Meshtastic Python CLI. Not exactly sure why this is the case since I didn’t rummage through the source code. (Is it fetching each set of information on a separate TCP/IP connection?)
  • I think I found a bug while running info. See below.

Over all: Cool, a self-contained Meshtastic CLI!

C:\Users\[redacted]\Documents>meshtastic-go.exe --port 192.168.xx.yy info

Radio Settings:
Node Number:             [redacted]
GPS:                     true
Number of Channels:      8
Firmware:                1.2.38.cf4e508
Message Timeout (msec):  300000
Min App Version:         20200

Radio Preferences:
PositionBroadcastSecs:   panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x28 pc=0x115095e]

goroutine 1 [running]:
main.printRadioPreferences(0x0, 0x0, 0x1247b10, 0xc0000d6100, 0x1, 0xc0000d6230, 0x0)
        /Users/lmatte/repos/meshtastic-go/pref.go:54 +0x31e
main.getRadioInfo(0x0, 0x0, 0x1247b10, 0xc0000d6100, 0x1, 0x11e2b0a, 0x1245308)
        /Users/lmatte/repos/meshtastic-go/info.go:118 +0x427
main.showAllRadioInfo(0xc0000dec00, 0x0, 0x0)
        /Users/lmatte/repos/meshtastic-go/info.go:45 +0xee*App).RunAsSubcommand(0xc00008b1e0, 0xc0000dea80, 0x0, 0x0)
        /Users/lmatte/go/pkg/mod/ +0x970*Command).startApp(0xc000116d80, 0xc0000dea80, 0xc0000aa0a8, 0x4)
        /Users/lmatte/go/pkg/mod/ +0x69b*Command).Run(0xc000116d80, 0xc0000dea80, 0x0, 0x0)
        /Users/lmatte/go/pkg/mod/ +0x98d*App).RunContext(0xc00008b040, 0x1245298, 0xc0000aa140, 0xc0000de000, 0x4, 0x4, 0x0, 0x0)
        /Users/lmatte/go/pkg/mod/ +0x825*App).Run(...)
        /Users/lmatte/repos/meshtastic-go/cli.go:278 +0x1be5
        /Users/lmatte/repos/meshtastic-go/main.go:6 +0x27

Thank you for the detailed feedback!

  • This is an easy change, I’ll include it in the next release. That use case makes sense to help make the CLI more reliable for more edge cases.
  • This is a bug I introduced in my last release. It will be fixed in the next release
  • The help command is built in from the CLI package I’m using. I’ll check into passing it a value
  • The info command is slower now because of a difference in how Go handles TCP sockets. I found I had to set an explicit timeout since the FromRadio packets don’t announce in a consistent way when they end. I’m planning on seeing how I can lower this timeout in the future.

That is indeed a bug as well! I’ll take a look and include the fix in the next release.

1 Like

For what it’s worth, I’m not sure anyone’s crazy enough to try to pass in --help true or --help false except just to try to break it. :wink: But it is a little odd that --help accepts a single argument.