Skip to main content

zenyard-relay

zenyard-relay connects an MCP server running on a user's machine to the Zenyard backend, even when that machine is behind a NAT or firewall. It dials out to the backend so the server can be reached without exposing any inbound ports.

Run one zenyard-relay serve process per MCP server you want to expose. Each process is a transparent passthrough — it forwards traffic between the backend and the MCP server unchanged. Multiple servers on the same machine appear to the backend as a single device.

The MCP server can run as a local subprocess (stdio) or a remote HTTP endpoint (streamable-http).

Install

The relay ships as a Python wheel built by maturin; the wheel installs the native zenyard-relay binary into the environment's bin/ (or Scripts\ on Windows):

pip install zenyard-relay

Or build from source with a stable Rust toolchain (≥ 1.75):

cargo build --release

The binary lands at target/release/zenyard-relay. Wheels for the common platforms are published from .github/workflows/ci.yml (tests gate the wheel publish step).

One-time device setup

serve runs without any config file as long as --control-endpoint (or --api-url) and the ZENYARD_RELAY_TOKEN env var are supplied. For convenience, a shared ~/.zenyard/relay.json can hold the control endpoint (and optionally the token) so individual sidecars don't have to pass it on the command line:

zenyard-relay config init      # optional; writes a starter ~/.zenyard/relay.json
zenyard-relay config path      # prints the config path
zenyard-relay config validate  # validates the file
zenyard-relay relay-id         # prints this device's relay id (generating one if missing)

~/.zenyard/relay.json example:

{
  "config": {
    "control_endpoint": "wss://relay.zenyard.dev/relay/control",
    "device_description": "user-laptop (Linux)"
  }
}

Plugins that already have the backend HTTP API URL configured can pass it as-is — the relay swaps http/https for ws/wss and appends the fixed /relay/control path:

zenyard-relay serve --id <ID> --api-url http://localhost:30465/ ...

The same field is accepted in relay.json as "api_url" (mutually exclusive with "control_endpoint").

The auth token is preferred from ZENYARD_RELAY_TOKEN (keeps secrets out of the JSON file); config.token is the fallback.

Sidecar contract

zenyard-relay serve --id <UPSTREAM_ID> [--display-name <NAME>] [--description <TEXT>] [--tag K=V...]
    [--control-endpoint <URL> | --api-url <URL>]
    [--config <PATH>] [--log-level <LEVEL>] [--log-format <FMT>]
    (--command <CMD> [--arg <V>...] [--env K=V...] [--cwd <DIR>])
  | (--url <URL> [--header "Name: value"...])

--control-endpoint / --api-url may be omitted when ~/.zenyard/relay.json (or the file pointed at by --config) supplies one. ZENYARD_RELAY_TOKEN in the environment is preferred over config.token.

Example — stdio upstream:

zenyard-relay serve --id fs --display-name "Filesystem" \
    --command npx --arg -y --arg @modelcontextprotocol/server-filesystem --arg /tmp

Example — remote upstream:

zenyard-relay serve --id api --display-name "Example API" \
    --url https://api.example.com/mcp \
    --header "Authorization: Bearer ghp_..."

After connecting, the sidecar sends a single Hello frame carrying the connection identity (relay_id / upstream_id) and the initial metadata snapshot (display_name / description / tags). It then reads stdin line-by-line for update ops that mutate the announced metadata:

{"op":"update", "display_name":"Echo (renamed)"}
{"op":"update", "tags":{"file":"sample.exe"}}
{"op":"update", "description":"Decompilation tools for sample.exe"}

Each update op replaces the supplied fields and re-sends UpstreamUpdated. The sidecar logs lifecycle events (connections, sessions, auth failures) to stderr per --log-level / --log-format, and exits when stdin closes.

For "same resource → same upstream across restarts" semantics, derive --id deterministically from the resource (e.g. ida-<sha256(idb_path)>). Conflicting live claims on the same id from two sidecars trigger takeover at the backend: the newer connection wins, the older one's sessions continue until they close naturally.

Exit codes

Code Meaning
0 Ok
1 Generic error
2 Invalid configuration / fatal auth rejection
3 Superseded — another relay took over this (relay_id, upstream_id)

License

This project is licensed under the GNU Affero General Public License v3.0 only.

See the LICENSE file in this repository for the full license text.

Release files for zenyard-relay 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for zenyard-relay 0.1.2
File Size Uploaded
zenyard_relay-0.1.2.tar.gz 94.4 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for zenyard-relay 0.1.2
File
zenyard_relay-0.1.2-py3-none-win_amd64.whl Python 3 none Windows x86-64 Details
zenyard_relay-0.1.2-py3-none-musllinux_1_2_x86_64.whl Python 3 none Linux musl 1.2+ x86-64 Details
zenyard_relay-0.1.2-py3-none-musllinux_1_2_aarch64.whl Python 3 none Linux musl 1.2+ ARM64 Details
zenyard_relay-0.1.2-py3-none-manylinux_2_28_aarch64.whl Python 3 none Linux glibc 2.28+ ARM64 Details
zenyard_relay-0.1.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl Python 3 none Linux glibc 2.17+ x86-64 Details
zenyard_relay-0.1.2-py3-none-macosx_11_0_arm64.whl Python 3 none macOS 11.0+ ARM64 Details
zenyard_relay-0.1.2-py3-none-macosx_10_12_x86_64.whl Python 3 none macOS 10.12+ x86-64 Details

Total release size:33.0 MB

Release files / zenyard_relay-0.1.2.tar.gz

Download URL zenyard_relay-0.1.2.tar.gz
Size 94.4 kB
Tags Source
SHA-256 checksum
How to use checksums
7d0270e1656ce506157c996e75963624541687817bef65218473807d214ec091
BLAKE2b-256 checksum
How to use checksums
fa3679b94919a6f0995151e5a17645ce05ccfb06408b1866fda23cd31b77de06
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 14, 2026.

Transparency log

Release files / zenyard_relay-0.1.2-py3-none-win_amd64.whl

Download URL zenyard_relay-0.1.2-py3-none-win_amd64.whl
Size 4.7 MB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
605215ecaedb5b0881512987953ce078023257e6efe95858f59c4be950eb6e63
BLAKE2b-256 checksum
How to use checksums
c671d0f5dcb49eec1b36b562fcc26047a76bd2786ba0391cbe0e4bab187536c5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 14, 2026.

Transparency log

Release files / zenyard_relay-0.1.2-py3-none-musllinux_1_2_x86_64.whl

Download URL zenyard_relay-0.1.2-py3-none-musllinux_1_2_x86_64.whl
Size 5.0 MB
Tags Linux musl 1.2+ x86-64 Python 3
SHA-256 checksum
How to use checksums
5871ab69ae38ac3eb0ce882acfbcbc77c98ad626dab1725f36e08ce04958e42e
BLAKE2b-256 checksum
How to use checksums
83559e10ad17ebbd43a244434a1c25599901b0882f868b6068d3d71fd95dee30
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 14, 2026.

Transparency log

Release files / zenyard_relay-0.1.2-py3-none-musllinux_1_2_aarch64.whl

Download URL zenyard_relay-0.1.2-py3-none-musllinux_1_2_aarch64.whl
Size 4.6 MB
Tags Linux musl 1.2+ ARM64 Python 3
SHA-256 checksum
How to use checksums
7629a3321f56dd18e80df8920fdaf6365215b241e174e7c7d03c5f5cb7f03e23
BLAKE2b-256 checksum
How to use checksums
c900a02ce254ca56114c29b067409e4228d6e8af6b7356624cb166160ec6f83d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 14, 2026.

Transparency log

Release files / zenyard_relay-0.1.2-py3-none-manylinux_2_28_aarch64.whl

Download URL zenyard_relay-0.1.2-py3-none-manylinux_2_28_aarch64.whl
Size 4.5 MB
Tags Linux glibc 2.28+ ARM64 Python 3
SHA-256 checksum
How to use checksums
ad89de4055c7a16d2b03172c7a9861e10fe3c59cb6dc8a9dcd4700c4e964c42d
BLAKE2b-256 checksum
How to use checksums
3165275190071ae36b2b32e1d484d53a5b63b2f8da855716ed92db3e9277a90d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 14, 2026.

Transparency log

Release files / zenyard_relay-0.1.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL zenyard_relay-0.1.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 4.8 MB
Tags Linux glibc 2.17+ x86-64 Python 3
SHA-256 checksum
How to use checksums
1c3d79022a6d0bc976b2b6bc17ee7af178a42ec1361b4348ba9e44093bda5408
BLAKE2b-256 checksum
How to use checksums
2e7027049c3abb36c1252c4a5f123c9a61ad631dc7d5bcf8194a3004a61bd591
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 14, 2026.

Transparency log

Release files / zenyard_relay-0.1.2-py3-none-macosx_11_0_arm64.whl

Download URL zenyard_relay-0.1.2-py3-none-macosx_11_0_arm64.whl
Size 4.6 MB
Tags Python 3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
de84f85f36106a1e3dfc8b73e47e10a395e889011c94fc0e297ccc0b27036b3f
BLAKE2b-256 checksum
How to use checksums
50725f5b0668759e50acdff7c0ca4c327170a0b2c372209470f0eb263264cc6d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 14, 2026.

Transparency log

Release files / zenyard_relay-0.1.2-py3-none-macosx_10_12_x86_64.whl

Download URL zenyard_relay-0.1.2-py3-none-macosx_10_12_x86_64.whl
Size 4.8 MB
Tags Python 3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
275f081de892e4c7bca126af47608f16a1cc3ddc888d758789d51d32f2ff5926
BLAKE2b-256 checksum
How to use checksums
44a2406b837cf80a1a90929a70afc2d802c50ed4a44dfb9bc06e1e69885a7836
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 14, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.2 This release

8 release files

0.1.1

8 release files

0.1.0

8 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page