MCP server for ROS 2 — exposes robot capabilities as AI-callable tools
Project description
scry-connect
MCP server for ROS 2 — exposes your robot's topics, nodes, services, parameters, actions, diagnostics, and introspection tools to AI agents.
Pairs with the Scry Android app.
Install
Pick the path that matches how your robot is deployed. All three install
the same scry-connect from PyPI — they just package it differently.
Option A — one-line installer (Docker or bare-metal, auto-detect)
curl -fsSL https://raw.githubusercontent.com/phaneron-robotics/scry-web/master/install.sh | bash
The script detects your ROS distro, picks Docker if available else pip,
writes a systemd --user unit, starts the service, and prints a
pairing QR. Re-running upgrades in place. Mode override:
SCRY_INSTALL_MODE=docker bash or SCRY_INSTALL_MODE=pip bash.
Option B — sidecar Docker container
Drop into your existing docker-compose.yml:
services:
scry-connect:
image: ghcr.io/phaneron-robotics/scry-connect:${ROS_DISTRO:-jazzy}
network_mode: host
ipc: host
pid: host
restart: unless-stopped
environment:
- ROS_DOMAIN_ID=${ROS_DOMAIN_ID:-0}
volumes:
- scry_config:/home/scry/.config/scry
- scry_audit:/var/log/scry
volumes:
scry_config:
scry_audit:
A turnkey reference compose with every tunable surfaced lives at docker/docker-compose.yml.
| Tag | Resolves to |
|---|---|
:humble, :jazzy, :kilted, :lyrical, :rolling |
Per-ROS-distro images (multi-arch: amd64 + arm64) |
:0.1.0-jazzy |
Pinned version on jazzy |
:latest |
Most recent stable release on the LTS distro (jazzy today) |
Option C — add scry-connect to your own robot image
If you already publish a robot Docker image, append one line to your
Dockerfile and run scry-connect alongside your existing nodes:
RUN pip install scry-connect
No second ROS install required — scry-connect uses the rclpy
that's already in your image.
Option D — bare-metal pip (no Docker)
source /opt/ros/$ROS_DISTRO/setup.bash
pip install --user scry-connect
scry-connect
A reference systemd user unit is written automatically by Option A in pip mode.
Prereleases (alpha / beta / rc) live on TestPyPI:
pip install -i https://test.pypi.org/simple/ scry-connect
Run
# Defaults to 0.0.0.0:5339 in open mode (LAN-only, no token).
scry-connect
# Common overrides
scry-connect --port 5339 --log-level INFO
scry-connect --token # token mode; prints QR for the phone
scry-connect --mtls # client-cert mode
scry-connect --skip-ros-check # smoke test without rclpy
Endpoints
| Path | Method | Description |
|---|---|---|
/mcp |
POST/GET | MCP JSON-RPC (Streamable HTTP) |
/stream?topic=/odom&rate=10 |
GET | SSE topic stream |
/health |
GET | Health check |
Tools exposed
22 tools grouped into: Topics, Nodes, Services, Parameters, Actions, Diagnostics, Logs, Introspection, System. See docs/mcp-tools-reference.md.
Config (env vars)
| Variable | Default | Description |
|---|---|---|
SCRY_HOST |
0.0.0.0 |
Bind address |
SCRY_PORT |
5339 |
HTTP port |
SCRY_RATE_LIMIT |
10 |
Tool calls per second |
SCRY_LOG_LEVEL |
INFO |
Log level |
SCRY_AUTH_MODE |
open |
open | token | mtls |
SCRY_TOKEN |
(unset) | Force token mode with this shared token |
SCRY_PUBLIC_INTERNET |
0 |
In open mode, accept non-LAN callers |
SCRY_REQUIRE_DEADMAN |
0 |
Writes need /scry/enable heartbeat |
SCRY_AUDIT_LOG |
(unset) | Append JSONL audit trail to this path |
SCRY_MDNS |
1 |
Advertise _scry._tcp via Zeroconf |
ROS_DOMAIN_ID |
(inherited) | ROS 2 domain ID |
RMW_IMPLEMENTATION |
(inherited) | DDS/RMW implementation |
Development
Setup
# Editable install + dev dependencies
pip install -e ".[dev]"
# Install pre-commit hooks (run once per fresh clone)
pip install pre-commit
pre-commit install
After pre-commit install, every git commit automatically runs ruff
(auto-fix) + ruff format on the staged Python files. If anything was
fixed, the commit is rejected — git add the fixes and commit again.
Manual lint commands
# Run pre-commit against every file (not just staged)
pre-commit run --all-files
# Run ruff directly
ruff check scry_connect tests # report issues
ruff check --fix scry_connect tests # auto-fix what can be fixed
ruff format scry_connect tests # apply formatter
Tests
pytest tests/
Note: many tests require a working ROS 2 environment (rclpy). In CI we only run lint + build; tests run on a real robot or local ROS 2 install.
CI / release pipeline
| Workflow | Trigger | What it does |
|---|---|---|
| CI | PR to master, push to master, manual | ruff check + format check, python -m build (sdist + wheel) |
| Release | Tag matching v*, manual |
Build, publish to PyPI / TestPyPI (Trusted Publishing — no API key needed), push to ghcr.io/phaneron-robotics/scry-connect, create GitHub Release |
| Dependency Graph | Auto-managed | Tracks third-party deps for security alerts |
To cut a release: bump version in pyproject.toml, merge the bump PR,
then tag the merge commit. Prerelease tags (v0.1.0-beta.1) route to
TestPyPI + a prerelease GitHub Release. Stable tags (v0.1.0) route
to PyPI proper and the Docker image gets the latest tag.
See docs/PYPI_SETUP.md for the one-time PyPI Trusted Publishing setup.
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 scry_connect-0.1.2.tar.gz.
File metadata
- Download URL: scry_connect-0.1.2.tar.gz
- Upload date:
- Size: 158.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
caafbe26e3d312a78188d47460836e9028a3d9e3b2f12393e296a5a5a33a8dab
|
|
| MD5 |
de138d29507b88e2ef476a050b416737
|
|
| BLAKE2b-256 |
4241aec490ccd9173428de058e3544f60f02a58f1db2c58a6c8a00001963b9f5
|
Provenance
The following attestation bundles were made for scry_connect-0.1.2.tar.gz:
Publisher:
release.yml on phaneron-robotics/scry-connect
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
scry_connect-0.1.2.tar.gz -
Subject digest:
caafbe26e3d312a78188d47460836e9028a3d9e3b2f12393e296a5a5a33a8dab - Sigstore transparency entry: 1630160822
- Sigstore integration time:
-
Permalink:
phaneron-robotics/scry-connect@c5841e95d80107151eab0f19886a05987b3e9474 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/phaneron-robotics
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c5841e95d80107151eab0f19886a05987b3e9474 -
Trigger Event:
push
-
Statement type:
File details
Details for the file scry_connect-0.1.2-py2.py3-none-any.whl.
File metadata
- Download URL: scry_connect-0.1.2-py2.py3-none-any.whl
- Upload date:
- Size: 148.0 kB
- Tags: Python 2, Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
defaa9b0650fe3c30aafe015134a5923a07aaeebd67c229d77d2d5206c724bb2
|
|
| MD5 |
589c61d1ca57f543e51804a0a5fd3d3d
|
|
| BLAKE2b-256 |
a8967f062eedad88c4d7ad9c7c346c701318ce28f66e9bf798e8699395518037
|
Provenance
The following attestation bundles were made for scry_connect-0.1.2-py2.py3-none-any.whl:
Publisher:
release.yml on phaneron-robotics/scry-connect
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
scry_connect-0.1.2-py2.py3-none-any.whl -
Subject digest:
defaa9b0650fe3c30aafe015134a5923a07aaeebd67c229d77d2d5206c724bb2 - Sigstore transparency entry: 1630160842
- Sigstore integration time:
-
Permalink:
phaneron-robotics/scry-connect@c5841e95d80107151eab0f19886a05987b3e9474 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/phaneron-robotics
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c5841e95d80107151eab0f19886a05987b3e9474 -
Trigger Event:
push
-
Statement type: