I’m posting this initially as a request for feedback, since I’m not sure if it’s possible to implement this with MeshCore. The idea is to replicate what MeshMonitor currently does with virtual nodes, let me explain.
A virtual node would involve having RemoteTerm listen on a port and act as a relay to the actual MeshCore node, like this:
Mobile App ┐
Other App ├─ Virtual Node (5000) ─ RemoteTerm ─ MeshCore Node (5000)
Some Client ┘
This way, you could have multiple applications connected to the same node.
As I understand it, the “trick” lies in serializing the process. You support multiple connections, but instead of running them in parallel, you queue them one after another.
Obviously, this is just a suggestion, and as I mentioned at the beginning, I’m not sure if it’s possible to do with MeshCore.
I’m posting this initially as a request for feedback, since I’m not sure if it’s possible to implement this with MeshCore. The idea is to replicate what [MeshMonitor currently does with virtual nodes](https://meshmonitor.org/configuration/virtual-node.html), let me explain.
A virtual node would involve having RemoteTerm listen on a port and act as a relay to the actual MeshCore node, like this:
```
Mobile App ┐
Other App ├─ Virtual Node (5000) ─ RemoteTerm ─ MeshCore Node (5000)
Some Client ┘
```
This way, you could have multiple applications connected to the same node.
As I understand it, the “trick” lies in serializing the process. You support multiple connections, but instead of running them in parallel, you queue them one after another.
Obviously, this is just a suggestion, and as I mentioned at the beginning, I’m not sure if it’s possible to do with MeshCore.
<!-- github-sync-id:4341101446 -->
why not use actual meshmonitor then before remoteterm?
As far as I know, the virtual node only works with Meshtastic.
> why not use actual meshmonitor then before remoteterm?
As far as I know, the virtual node only works with Meshtastic.
<!-- github-comment-id:4333900773 -->
ah, i see, that's meshtastic, sorry. i'm using my own ai-coded simple multiplexer, not sure if it works correctly, but it works for me. i'm using it with official meshcore app to monitor live noise floor log or live discover of repeaters because remoteterm misses this)
@ogarcia
ah, i see, that's meshtastic, sorry. i'm using my own ai-coded simple multiplexer, not sure if it works correctly, but it works for me. i'm using it with official meshcore app to monitor live noise floor log or live discover of repeaters because remoteterm misses this)
https://gist.github.com/hackruu/03b1c5902b62a42c8af8ddef93663f16 maybe you can fit it your workflow
<!-- github-comment-id:4334039690 -->
> https://gist.github.com/hackruu/03b1c5902b62a42c8af8ddef93663f16 maybe you can fit it your workflow
I'll take a look, I'm sure it'll work for me 👍
<!-- github-comment-id:4334902019 -->
Just to toss it in the ring (I know discord folks have already seen this), I vibe coded a prototype tcp proxy as well at https://github.com/jkingsman/Remote-Terminal-for-MeshCore/tree/tcp-proxy (enable with env var MESHCORE_TCP_PROXY_ENABLED=true). If there's a consensus on superior proxy, happy to link to it in the readme.
Also
live noise floor log or live discover of repeaters
RemoteTerm exposes noise floor on the statistics page, and discovery packets are supported from the radio settings page, if those are what you mean 🙂
Just to toss it in the ring (I know discord folks have already seen this), I vibe coded a prototype tcp proxy as well at https://github.com/jkingsman/Remote-Terminal-for-MeshCore/tree/tcp-proxy (enable with env var `MESHCORE_TCP_PROXY_ENABLED=true`). If there's a consensus on superior proxy, happy to link to it in the readme.
Also
> live noise floor log or live discover of repeaters
RemoteTerm exposes noise floor on the statistics page, and discovery packets are supported from the radio settings page, if those are what you mean 🙂
<!-- github-comment-id:4336389954 -->
I was just getting started with a pure TCP approach, which does work, but of course, if one client does something, the other one doesn't know anything about it. Plus, the node doesn't really appreciate it when you reset its counters.
> I vibe coded a prototype tcp proxy as well at https://github.com/jkingsman/Remote-Terminal-for-MeshCore/tree/tcp-proxy.
Yes, this is definitely a much better solution.
I was just getting started with a pure TCP approach, which does work, but of course, if one client does something, the other one doesn't know anything about it. Plus, the node doesn't really appreciate it when you reset its counters.
<!-- github-comment-id:4336788261 -->
The noise floor is sampled once per minute; is that what you mean? If not, are you meaning impulse repeater discovery or addition on advert? RemoteTerm will add new repeaters as soon as they're advertised (not trying to derail this discussion about TCP proxying; just curious)
The noise floor is sampled once per minute; is that what you mean? If not, are you meaning impulse repeater discovery or addition on advert? RemoteTerm will add new repeaters as soon as they're advertised (not trying to derail this discussion about TCP proxying; just curious)
<!-- github-comment-id:4337312869 -->
yes, official app shows live noise floor with 1update/s interval.
same goes for discover repeaters button, i get repeaters names as they respond, not when discover timeout is reached as in remoteterm
yes, official app shows live noise floor with 1update/s interval.
same goes for discover repeaters button, i get repeaters names as they respond, not when discover timeout is reached as in remoteterm
<!-- github-comment-id:4337326573 -->
I'm testing it thoroughly right now. The client connects to the proxy just fine, but beyond that, it doesn't do much else (at least in the messaging part, which is what I'm testing). If the node receives a message, it reaches RemoteTerm correctly but not the proxy client, and if the proxy client sends a message, it appears to simply be rejected with this message {'error_code': 2, 'code_string': 'ERR_CODE_NOT_FOUND'}.
> I vibe coded a prototype tcp proxy as well at https://github.com/jkingsman/Remote-Terminal-for-MeshCore/tree/tcp-proxy
I'm testing it thoroughly right now. The client connects to the proxy just fine, but beyond that, it doesn't do much else (at least in the messaging part, which is what I'm testing). If the node receives a message, it reaches RemoteTerm correctly but not the proxy client, and if the proxy client sends a message, it appears to simply be rejected with this message `{'error_code': 2, 'code_string': 'ERR_CODE_NOT_FOUND'}`.
<!-- github-comment-id:4338064337 -->
Ugh, yeah. Emulating a line level protocol is miserable. I feel like I'm growing closer and closer to just abandoning the idea; it's not a maintenance burden I really think makes sense for a project like this. I'm happy to point folks to other projects, but I don't think maintaining what is, in essence, a MeshCore radio simulator is reasonable.
Ugh, yeah. Emulating a line level protocol is miserable. I feel like I'm growing closer and closer to just abandoning the idea; it's not a maintenance burden I really think makes sense for a project like this. I'm happy to point folks to other projects, but I don't think maintaining what is, in essence, a MeshCore radio simulator is reasonable.
<!-- github-comment-id:4338167103 -->
Yes, I understand it’s not simple. In fact, upon closer examination, given the way communication with a Meshcore node is currently implemented, what Meshmonitor would need to implement is exactly that: an emulation.
But I've thought of something that might be simpler: a stripped-down emulation. Basically, when a client connects, it would provide the list of known nodes and the list of channels, and then send conversations in real time as they're received (no need to store history). If that client sends a message, RemoteTerm would pick it up and send it. You don’t need anything else. The whole configuration thing and so on isn’t operational; if you want to change any of that, you do it from RemoteTerm or disconnect and connect whatever you want in its place.
Yes, I understand it’s not simple. In fact, upon closer examination, given the way communication with a Meshcore node is currently implemented, what Meshmonitor would need to implement is exactly that: an emulation.
But I've thought of something that might be simpler: a stripped-down emulation. Basically, when a client connects, it would provide the list of known nodes and the list of channels, and then send conversations in real time as they're received (no need to store history). If that client sends a message, RemoteTerm would pick it up and send it. You don’t need anything else. The whole configuration thing and so on isn’t operational; if you want to change any of that, you do it from RemoteTerm or disconnect and connect whatever you want in its place.
<!-- github-comment-id:4346438465 -->
That's already implemented in my branch. It works perfectly for me locally. The trick is figuring out all the different quirks that various clients have or engage in to get the radio to behave; as you can see on this thread, and as has been discussed on discord, there are a number of clients that still have problems with it despite it working fine for me with the official Android application.
It's not the difficulty to build; it's been built. It's the difficulty to troubleshoot and get working smoothly with all clients on all platforms, and to keep it so, but I don't particularly care for haha
That's already implemented in my branch. It works perfectly for me locally. The trick is figuring out all the different quirks that various clients have or engage in to get the radio to behave; as you can see on this thread, and as has been discussed on discord, there are a number of clients that still have problems with it despite it working fine for me with the official Android application.
It's not the difficulty to build; it's been built. It's the difficulty to troubleshoot and get working smoothly with all clients on all platforms, and to keep it so, but I don't particularly care for haha
<!-- github-comment-id:4346498791 -->
Yes, I actually cloned the branch and set up a container with it, but it’s not quite working right. I’m connecting a client I built myself, which might not be 100% compatible with what’s already implemented.
The problem is probably with the channel mapping. I'll have to look into it more closely...
Yes, I actually cloned the branch and set up a container with it, but it’s not quite working right. I’m connecting a [client I built myself](https://github.com/ogarcia/mmrelay-meshcore-plugin), which might not be 100% compatible with what’s already implemented.
The problem is probably with the channel mapping. I'll have to look into it more closely...
<!-- github-comment-id:4346660399 -->
Playing with the idea of creating a seperate project, that proxy between Meshcore apps and RemoteTerm, and using RemoteTerm as the source of truth.
Playing with the idea of creating a seperate project, that proxy between Meshcore apps and RemoteTerm, and using RemoteTerm as the source of truth.
<!-- github-comment-id:4361274056 -->
Right now, I'm testing out several modifications to the implementation I'm working on as a client. If I connect directly to the node, everything works fine. If I connect through RemoteTerm, I always get a “Channel does not exist” error:
My code is straightforward: it calls mc.commands.send_chan_msg(idx, message), where idx is the channel’s numeric ID. I’m not exactly sure why the relay that RemoteTerm uses isn’t accepting it, but that’s just how it is.
Right now, I'm testing out several modifications to the implementation I'm working on as a client. If I connect directly to the node, everything works fine. If I connect through RemoteTerm, I always get a “Channel does not exist” error:
```
{'error_code': 2, 'code_string': 'ERR_CODE_NOT_FOUND'}
```
My code is straightforward: it calls `mc.commands.send_chan_msg(idx, message)`, where idx is the channel’s numeric ID. I’m not exactly sure why the relay that RemoteTerm uses isn’t accepting it, but that’s just how it is.
<!-- github-comment-id:4361409628 -->
Ahh yeah I was having some difficulty keeping things straight between RemoteTerm channel I'd and the loaded slot. One of the many glitches that make me hesitant to mainline this in any way haha
Ahh yeah I was having some difficulty keeping things straight between RemoteTerm channel I'd and the loaded slot. One of the many glitches that make me hesitant to mainline this in any way haha
<!-- github-comment-id:4361532478 -->
Ahh yeah I was having some difficulty keeping things straight between RemoteTerm channel I'd and the loaded slot. One of the many glitches that make me hesitant to mainline this in any way haha
That's right; in fact, the log itself tells you so:
2026-05-01 20:42:10 - app.tcp_proxy.session - WARNING - [('192.168.1.123', 50966)] No channel at slot 0
It is certainly no easy task to build a virtual node that behaves just like the real one.
> Ahh yeah I was having some difficulty keeping things straight between RemoteTerm channel I'd and the loaded slot. One of the many glitches that make me hesitant to mainline this in any way haha
That's right; in fact, the log itself tells you so:
```
2026-05-01 20:42:10 - app.tcp_proxy.session - WARNING - [('192.168.1.123', 50966)] No channel at slot 0
```
It is certainly no easy task to build a virtual node that behaves just like the real one.
<!-- github-comment-id:4361568138 -->
I'm gonna close this for now. I'll keep the code in the branch, but I think this is something that needs a lot more love than I'm wanting to give it right now hah.
I'm gonna close this for now. I'll keep the code in the branch, but I think this is something that needs a lot more love than I'm wanting to give it right now hah.
<!-- github-comment-id:4446300196 -->
In the end, I ended up making myself a little splitter. It works for me, but there might be some unchecked bugs. If you're interested, I've left it here: https://github.com/ogarcia/coresplitter
In the end, I ended up making myself a little splitter. It works for me, but there might be some unchecked bugs. If you're interested, I've left it here: https://github.com/ogarcia/coresplitter
<!-- github-comment-id:4502126774 -->
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
I’m posting this initially as a request for feedback, since I’m not sure if it’s possible to implement this with MeshCore. The idea is to replicate what MeshMonitor currently does with virtual nodes, let me explain.
A virtual node would involve having RemoteTerm listen on a port and act as a relay to the actual MeshCore node, like this:
This way, you could have multiple applications connected to the same node.
As I understand it, the “trick” lies in serializing the process. You support multiple connections, but instead of running them in parallel, you queue them one after another.
Obviously, this is just a suggestion, and as I mentioned at the beginning, I’m not sure if it’s possible to do with MeshCore.
why not use actual meshmonitor then before remoteterm?
As far as I know, the virtual node only works with Meshtastic.
@ogarcia
ah, i see, that's meshtastic, sorry. i'm using my own ai-coded simple multiplexer, not sure if it works correctly, but it works for me. i'm using it with official meshcore app to monitor live noise floor log or live discover of repeaters because remoteterm misses this)
https://gist.github.com/hackruu/03b1c5902b62a42c8af8ddef93663f16 maybe you can fit it your workflow
I'll take a look, I'm sure it'll work for me 👍
Just to toss it in the ring (I know discord folks have already seen this), I vibe coded a prototype tcp proxy as well at https://github.com/jkingsman/Remote-Terminal-for-MeshCore/tree/tcp-proxy (enable with env var
MESHCORE_TCP_PROXY_ENABLED=true). If there's a consensus on superior proxy, happy to link to it in the readme.Also
RemoteTerm exposes noise floor on the statistics page, and discovery packets are supported from the radio settings page, if those are what you mean 🙂
Yes, this is definitely a much better solution.
I was just getting started with a pure TCP approach, which does work, but of course, if one client does something, the other one doesn't know anything about it. Plus, the node doesn't really appreciate it when you reset its counters.
@jkingsman it's not as live(realtime) as in official app :)
The noise floor is sampled once per minute; is that what you mean? If not, are you meaning impulse repeater discovery or addition on advert? RemoteTerm will add new repeaters as soon as they're advertised (not trying to derail this discussion about TCP proxying; just curious)
yes, official app shows live noise floor with 1update/s interval.
same goes for discover repeaters button, i get repeaters names as they respond, not when discover timeout is reached as in remoteterm
not the dealbreakers but it's why i'm using this tcp multiplexer
I'm testing it thoroughly right now. The client connects to the proxy just fine, but beyond that, it doesn't do much else (at least in the messaging part, which is what I'm testing). If the node receives a message, it reaches RemoteTerm correctly but not the proxy client, and if the proxy client sends a message, it appears to simply be rejected with this message
{'error_code': 2, 'code_string': 'ERR_CODE_NOT_FOUND'}.Ugh, yeah. Emulating a line level protocol is miserable. I feel like I'm growing closer and closer to just abandoning the idea; it's not a maintenance burden I really think makes sense for a project like this. I'm happy to point folks to other projects, but I don't think maintaining what is, in essence, a MeshCore radio simulator is reasonable.
Yes, I understand it’s not simple. In fact, upon closer examination, given the way communication with a Meshcore node is currently implemented, what Meshmonitor would need to implement is exactly that: an emulation.
But I've thought of something that might be simpler: a stripped-down emulation. Basically, when a client connects, it would provide the list of known nodes and the list of channels, and then send conversations in real time as they're received (no need to store history). If that client sends a message, RemoteTerm would pick it up and send it. You don’t need anything else. The whole configuration thing and so on isn’t operational; if you want to change any of that, you do it from RemoteTerm or disconnect and connect whatever you want in its place.
That's already implemented in my branch. It works perfectly for me locally. The trick is figuring out all the different quirks that various clients have or engage in to get the radio to behave; as you can see on this thread, and as has been discussed on discord, there are a number of clients that still have problems with it despite it working fine for me with the official Android application.
It's not the difficulty to build; it's been built. It's the difficulty to troubleshoot and get working smoothly with all clients on all platforms, and to keep it so, but I don't particularly care for haha
Yes, I actually cloned the branch and set up a container with it, but it’s not quite working right. I’m connecting a client I built myself, which might not be 100% compatible with what’s already implemented.
The problem is probably with the channel mapping. I'll have to look into it more closely...
Playing with the idea of creating a seperate project, that proxy between Meshcore apps and RemoteTerm, and using RemoteTerm as the source of truth.
Right now, I'm testing out several modifications to the implementation I'm working on as a client. If I connect directly to the node, everything works fine. If I connect through RemoteTerm, I always get a “Channel does not exist” error:
My code is straightforward: it calls
mc.commands.send_chan_msg(idx, message), where idx is the channel’s numeric ID. I’m not exactly sure why the relay that RemoteTerm uses isn’t accepting it, but that’s just how it is.Ahh yeah I was having some difficulty keeping things straight between RemoteTerm channel I'd and the loaded slot. One of the many glitches that make me hesitant to mainline this in any way haha
That's right; in fact, the log itself tells you so:
It is certainly no easy task to build a virtual node that behaves just like the real one.
I'm gonna close this for now. I'll keep the code in the branch, but I think this is something that needs a lot more love than I'm wanting to give it right now hah.
In the end, I ended up making myself a little splitter. It works for me, but there might be some unchecked bugs. If you're interested, I've left it here: https://github.com/ogarcia/coresplitter