Outbound-only edge daemon for the SignalMesh Submesh Protocol — wrap local software as callable mesh coords with zero inbound ports.
Project description
signalmesh-meshd
Outbound-only edge daemon for the SignalMesh Submesh Protocol. It holds one
persistent WebSocket to the SignalMesh cloud, walks
~/.signalmesh/harnesses/*/SKILL.md for op manifests, and executes
call_requests as local subprocesses — no inbound ports, ever.
Install
pipx install signalmesh-meshd
Not on PyPI yet? Install straight from the built wheel:
pipx install /path/to/signalmesh_meshd-0.1.3-py3-none-any.whl
Quick start
Pair once — exchanges your SignalMesh key for a device_id + device_token,
written to ~/.signalmesh/meshd.yaml at mode 0600:
meshd pair --key=smesh-XXXXXX --name=my-desktop
Connect — opens the outbound WebSocket, advertises discovered ops, and blocks
serving call_requests until you kill it:
meshd connect
Invoke a coord from the cloud (this is what the SignalMesh backend does on your behalf when a mesh caller routes to your device):
curl -X POST https://acecalisto3-signalmesh.hf.space/api/submesh/call \
-H "Content-Type: application/json" \
-H "X-SignalMesh-Key: smesh-XXXXXX" \
-d '{"coord": "submesh.my_desktop.echo_test.say", "input": {"msg": "hello mesh"}}'
Writing a SKILL.md manifest
Drop a directory under ~/.signalmesh/harnesses/<harness-name>/ containing a
SKILL.md with YAML frontmatter. meshd parses the frontmatter block, refuses
any exec argv containing shell metacharacters, and advertises one coord per
subcommand.
~/.signalmesh/harnesses/echo-test/SKILL.md:
---
binary: /bin/echo
subcommands:
- op_id: say
exec: ["{msg}"]
summary: "Echo a string back through the mesh."
params_schema:
msg: string
timeout_ms: 5000
---
# echo-test
Minimal harness proving the mesh call → subprocess → response round trip.
This advertises submesh.<device_name>.echo_test.say, callable with
{"msg": "..."}.
Android apps (APK) as mesh nodes
Any Android app reachable over adb can be a submesh node — mesh-anything
includes your phone. Point meshd apk wrap at an installed package name or a
local .apk (it installs it first):
meshd apk wrap com.example.app
meshd apk wrap ~/Downloads/some-app.apk
This resolves the launcher activity and writes an adb-backed SKILL.md harness
exposing submesh.<device>.apk_<pkg>.{launch,stop,deeplink,tap,text,screenshot}.
Restart meshd connect and the app's coords are advertised to the mesh like
any other harness — same metachar guard, same shell=False execution.
Requires Android platform-tools (adb) and a device or emulator visible to
adb devices.
Android Studio toolchain as mesh capabilities
Wrap the SDK that ships with Android Studio — emulator, AVDs, adb — so a mesh caller can boot a headful emulator on your desktop, install builds, and drive demos/tests end-to-end:
meshd studio wrap # ~/Library/Android/sdk (or --sdk PATH)
meshd studio wrap-project ~/code/MyApp # wraps the project's ./gradlew
Coords advertised after meshd connect:
submesh.<device>.android_avds.list enumerate AVDs
submesh.<device>.android_emulator.boot boot an AVD headful (detached)
submesh.<device>.android_adb.{devices,kill,install,screenshot,wait_boot}
submesh.<device>.android_project_<name>.{assemble,install,unit_test,instrumented}
Emulator boot detaches via a generated launch script, so the mesh call
returns immediately while the emulator window appears on the host. Chain
boot → wait_boot → install → apk_<pkg>.launch → screenshot for a full
headful demo of a mobile app, driven entirely by mesh coords.
Safety model
Every argv token is checked against a shell-metachar denylist twice: once at
manifest-load time (before a coord is even advertised) and once again after
{param} substitution (before the subprocess actually runs) — a manifest
can't sneak a malicious literal past you, and a caller can't sneak one in
through input params either. Subprocesses always run with shell=False.
Path-typed params are additionally checked against each subcommand's
allow_paths glob list; anything that resolves outside the allowlist is
rejected before it ever reaches argv.
Links
- 🤗 HuggingFace Space (canonical): https://huggingface.co/spaces/acecalisto3/SignalMesh
- Live app (API endpoints): https://acecalisto3-signalmesh.hf.space
- Interactive lander: https://kyklos.io/submesh/
- Protocol docs: see the Space's
/api/submesh/*routes (device/pair,device/{id}/revoke,devices,edge,call)
License
MIT
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file signalmesh_meshd-0.1.6.tar.gz.
File metadata
- Download URL: signalmesh_meshd-0.1.6.tar.gz
- Upload date:
- Size: 18.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
af353819ef459590ecbf7371dada9e1aa292b81863ca4b1893a59f892b801439
|
|
| MD5 |
c37ca68553eff7c8b4cf9b871d4ae3a1
|
|
| BLAKE2b-256 |
a78a9395819d04e6b3bc4b64ab444606256cfabba750879a9797385a4adf1868
|
File details
Details for the file signalmesh_meshd-0.1.6-py3-none-any.whl.
File metadata
- Download URL: signalmesh_meshd-0.1.6-py3-none-any.whl
- Upload date:
- Size: 18.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
46f680ca765ee0153939906c34630648bf1b769a3e33ed0e58caa46f7fc57aa4
|
|
| MD5 |
98d4b4367f0d9cb93c8a58ccc5e68061
|
|
| BLAKE2b-256 |
5834d7a54d0b5d5101bb3760d7d03761be7e4354eeddda34222eba7904cec6bc
|