rstream CLI MCP について
rstream CLI MCPは、rstream CLIのセットアップ、トンネル、リモート操作をCodexなどのクライアントから利用できるようにします。rstreamのアウトバウンド型トンネル基盤を使い、ローカルサービスの公開や環境をまたいだ制御付きアクセスを行います。
主な機能
- 01トンネル経由でローカル・プライベートサービスに接続
- 02パブリック型とプライベート型のトンネルに対応
- 03WebTTYとリモート操作を提供
- 04ブラウザーフローによるCLIログイン
- 05doctorによる構造化診断
活用シーン
- 01テストやデモ用にローカルサービスを公開
- 02異なる環境のデバイスへアクセス
- 03自動化環境で設定診断を実行
- 04Codexからログイン承認を開始・完了
MCP 対応
ローカルstdio MCPサーバーは、Codexにrstreamの操作機能を提供します。ドキュメントには、認証を開始してトークンをローカル保存するrstream_auth_startとrstream_auth_pollが記載されています。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
rstream-go
rstream-go は、グローバルに分散されたエッジネットワークと軽量なエージェントを中心に構築されたセキュアな接続プラットフォーム rstream の Go SDK です。エージェントはローカル環境やプライベート環境から外向き専用のトンネルを維持し、エッジネットワークはトラフィックを認証し、アクセスのポリシーを適用して、リクエストをアップストリームサービスへルーティングします。rstream は HTTP および非 HTTP のワークロードに対応し、接続ログとメトリクスを通じてエンドツーエンドの可視性を提供します。
Go SDK はリファレンス実装です。rstream API の最も幅広い範囲をカバーし、プロトコルのサポートとトンネルのライフサイクル機能において最も完成度の高い SDK です。rstream CLI は Go で実装され、このリポジトリに含まれているため、SDK と CLI は同じ設定モデルと運用上の動作を共有します。
ネイティブ統合をお探しですか?C++ SDK は https://github.com/rstreamlabs/rstream-cpp で利用できます。
トンネルとは?
トンネルは、受信ポート、パブリック IP、NAT の変更を必要とせずにサービスを公開するためのセキュアな方法です。rstream では、トンネルはエッジネットワークへ外向きに確立されるため、アクセスを制御・可視化しながら、露出を抑えられます。
rstream で公開トンネルを作成すると、受信トラフィックをローカルサービスへルーティングする転送アドレスが割り当てられます。たとえば、localhost:8080 用のトンネルでは、https://abc123.rstream.io のような転送アドレスが提供され、HTTP リクエストがローカルポート 8080 に転送されます。
rstream の仕組み
rstream は、サービスやデバイスを実行する環境と rstream エッジネットワークの間に外向きトンネルを確立します。クライアントは、公開トンネルの場合は転送アドレスを使用し、プライベートトンネルの場合はトンネル識別子を使用してエッジに接続します。エッジは接続を認証し、ポリシーを適用して、既存のトンネル経路を通じてアップストリームサービスへトラフィックを転送します。
トンネルのトランスポートは暗号化され、エッジによる適用の判断はログとメトリクスに示されます。
トンネルの種類
rstream は、基本となる 2 種類のトンネルに対応しています。
バイトストリームトンネル(TCP のようなトンネル)は、HTTP や TLS などのプロトコル、およびカスタムのバイトストリームサービスに対して、信頼性の高い順序付きの伝送を提供します。
データグラムトンネル(UDP のようなトンネル)は、QUIC や DTLS などのプロトコル、およびカスタムのデータグラムサービスに対して、低遅延のメッセージ指向通信を提供します。
公開トンネルとプライベートトンネル
公開トンネルには、転送アドレスを通じて標準的なクライアント(ブラウザー、curl など)からアクセスできます。公開トンネルは、プロトコルやデプロイ方法に応じて、エッジ認証とアクセスポリシーを設定できます。
プライベートトンネルへの接続には rstream クライアントが必要です。プライベートトンネルには、パブリックな転送アドレスではなく、rstream ダイヤラーを通じて名前(指定されている場合)または ID でアクセスします。
ユースケース
ローカル開発:ネットワーク設定を変更せずに、テスト、デモ、共同作業用にローカルサービスを公開します。
フリート運用:一貫したアイデンティティ、ポリシー、可観測性のもとで、さまざまな環境にあるデバイスやマシンへのアクセスを制御します。
インフラストラクチャとプラットフォーム:rstream を内部ツール、CI ワークフロー、本番環境へのアクセス経路の接続レイヤーとして使用します。
生成 AI ワークフロー:アクセス範囲を限定し、監査可能な状態を維持しながら、ランナーやマシンのフリートに作業を分散します。
リアルタイムシステム:テレメトリ、ストリーミング、データグラムのワークロードにおける低遅延のトラフィックパターンをサポートします。
サポートされている機能
コアトンネリング:アウトバウンド専用の接続で、TCP 相当および UDP 相当のワークロード用トンネルを作成します。
マルチプロトコル対応:HTTP(1.1、2、3)、TLS、DTLS、QUIC に加え、HTTP トンネル内の WebSocket と WebTransport に対応しています。
アクセス制御:トンネルの設定に応じて、IP 制限、GeoIP ポリシー、相互 TLS、トークンベースのアクセス、アカウントベースのアクセスを利用できます。
運用状況の可視化:トラフィック、適用判断、パフォーマンス指標に関する接続ログとメトリクスを提供します。
トランスポート設定:IPv4/IPv6 の選択、DNS の上書き、インターフェースのバインド、HTTP CONNECT プロキシ、SOCKS5 プロキシ、および QUIC トランスポート用の MASQUE プロキシに対応しています。
耐障害性:安定した接続を実現する、長時間稼働するエージェント、再接続動作、トランスポートレベルの多重化を備えています。
制御チャネルの生存状態とペイロードのライフタイムは、意図的に分離されています。
ネゴシエーションされたハートビート猶予期間により、短時間のネットワーク中断を吸収します。その猶予期間を過ぎると、リスナーは新しいストリームの受付を停止して再接続します。一方、すでに受け付けたバイトストリームと登録済みの QUIC データグラムチャネルは、アプリケーションが閉じるかデータパス自体が終了するまで引き続き使用できます。トンネル、制御チャネル、クライアント、またはプロセスの明示的なシャットダウンでは、所有するセッションも引き続き閉じられます。そのため、SDK の呼び出し元は Accept から返された各接続を通常どおり所有し、ControlChannel.Done がトランスポート障害を報告した場合でも、その接続を閉じる必要があります。
サポートされているプロトコル
HTTP プロトコル:HTTP/1.1、HTTP/2(H2C)、WebSocket および WebTransport に対応した HTTP/3。
セキュアトランスポート:エージェントからエッジへの接続には TLS ベースおよび QUIC ベースのトランスポートを使用できます。また、デプロイ環境で有効にした場合は、公開するトンネルプロトコルとして DTLS と QUIC にも対応します。
ネットワークオプション:IPv4/IPv6、MPTCP、HTTP CONNECT、SOCKS5、QUIC トランスポート用の MASQUE CONNECT-UDP、カスタム DNS 解決。
互換性
rstream は Linux、macOS 13 以降、Windows と互換性があります。また、手動インストールにより、FreeBSD、OpenBSD、NetBSD などのほかの UNIX システムにも対応しています。
FIPS 140-3 プロファイル
rstream-go は、レビュー済みの Linux クライアント環境向けに、制限付きの FIPS 140-3 ビルドプロファイルを提供します。FIPS SDK と CLI のアーティファクトには、
NIST CMVP 検証済み Go Cryptographic Module、証明書 5247
が組み込まれており、使用されます。このモジュールの総合セキュリティレベルは 1 です。これらのアーティファクトでは、このモジュールとレビュー済みの
quic-go および webtransport-go のバージョンを固定し、モジュールを承認済みモードで実行します。また、除外対象のトランスポート、プロトコル、またはランタイム設定が要求された場合は、安全側に停止します。
該当するアーティファクトの表記は FIPS 140-3 Inside — Go Cryptographic Module、 Certificate #5247(総合セキュリティレベル 1) です。このレベルと証明書は組み込まれた Go 暗号モジュールに適用されます。rstream 製品全体は、独立した CMVP モジュール検証を受けていません。このプロファイルは、標準のマルチプロトコル配布版とは別のビルドです。
このプロファイルは、TLS/mTLS、直接 QUIC、通常の HTTP/3、および WebTransport 経由の認証済み E2E WebTTY に対応しています。WebTTY では、P-256/HKDF-SHA256/AES-256-GCM のランダムノンスプロトコルプロファイルを使用します。標準ビルドでは、このプロファイルまたは従来の X25519 プロファイルを使用できますが、FIPS ビルドで受け付けるのは前者のみです。
対応範囲、除外事項、ビルド手順、ランタイムの証跡、モジュールのアップグレード手順については、docs/010-fips-140-3-profile.md を参照してください。
インストール(rstream CLI)
このセクションのインストール方法では、rstream CLI バイナリとそのランタイム依存関係をインストールします。Go SDK をライブラリ依存関係としてインストールするものではありません。
ローカルビルド
現在のプラットフォーム上で、このリポジトリから CLI をローカルにビルドするには、次を実行します。
make
ビルドでは、検証済みの一時的な ICE 並行処理パッチが適用されます。 SDK の WebRTC ファイルシステムトランスポートを使用するアプリケーションも、 独自のビルドを準備する必要があります。Go は依存関係の置換設定を引き継ぎません。 Go のコマンドを直接実行する方法と導入手順については、 ICE patch guide を参照してください。
Debian/Ubuntu
Debian ベースのディストリビューションでは、インストーラーがパッケージ化された CLI バイナリと依存関係をデプロイします。
sudo /bin/bash -i -c "$(curl -fsSL https://rstream.io/scripts/install-debian.sh)"
macOS
macOS では、Homebrew tap を標準の CLI インストール方法として利用できます。
brew tap rstreamlabs/rstream && brew install rstream
Windows
Windows では、公式の WinGet Community Repository から rstream をインストールします。
winget install --id rstream.rstream --exact --source winget
winget が利用できない場合、または新しい安定版リリースが
まだ Community Repository に登録されていない場合は、PowerShell インストーラーを使用します。
& { Invoke-Expression ([System.Text.Encoding]::UTF8.GetString((Invoke-WebRequest -Uri 'https://rstream.io/scripts/install.ps1' -UseBasicParsing).Content)) }
手動インストール
一般的な環境では、CLI バイナリ用の手動インストーラースクリプトを使用します。
/bin/bash -i -c "$(curl -fsSL https://rstream.io/scripts/install.sh)"
Docker
コンテナーで CLI を実行する場合は、公開イメージをプルします。
docker pull rstream/rstream:latest
認証
開発マシンでの標準的な方法は、ブラウザーを使ったログインです。
rstream login
デフォルトでは、OAuth 2.0 Device Authorization Grant が使用されます。互換性確認用に、従来の rstream ログインフローも rstream login --auth-flow legacy で引き続き利用できます。
新しい rstream アカウントの場合、rstream login によって開かれるブラウザーステップで、ユーザーはサインアップまたはサインインし、CLI アクセスを承認します。
rstream codex setup の実行後、Codex はローカル MCP を通じて同じフローを開始できます。rstream_auth_start は承認 URL を返し、rstream_auth_poll は承認済みトークンをプロンプトに返すことなくローカルに保存します。プロバイダーが承認コードを URL に埋め込めない場合に限り、承認コードは別途返されます。デフォルトの MCP ログインスコープは制限されています。ユーザーが Codex にプロジェクトの作成やプロジェクト設定の変更を明示的に依頼した場合、rstream_auth_start はより広範な permissions 配列を要求でき、ホストされた承認ページにはその権限の付与が表示されます。
高度な認証モード(トークンベースのログイン、リモートデバイスフロー、プロジェクトスコープのコンテキスト)については、docs/001-cli-workflow.md を参照してください。
SDK のサンプルを実行する前に、CLI でプロジェクトコンテキストを設定してください(rstream project use <project-endpoint>)。SDK と CLI は同じ設定モデルと設定ファイルを共有します。
エージェントおよび CI のチェックには、次を実行します。
rstream doctor -o json
診断出力では、秘密情報を表示せずに、設定、コンテキスト、トークンのクレーム、Control plane API の認証、プロジェクトの解決、DNS、TLS、エンジンのインベントリを確認できます。Go アプリケーションでは doctor.Run を使用すると、CLI を呼び出さずに同じ構造化診断を取得できます。
標準の Go CLI および設定パッケージは、ベンダー固有の API を持つ HSM 用の外部 mTLS 署名者にも対応しています。ローカル実行ファイルが公開 ID と署名を提供し、rstream が TLS を処理します。このバックエンドは CGO がなくても動作します。
環境変数
これらの変数は、CLI と SDK の設定解決で共通して使用されます。通常の使用では設定コンテキストを優先し、自動化や制約のある環境ではオーバーライドを使用してください。
RSTREAM_CONFIG:CLI の設定ファイルパスをオーバーライドします。RSTREAM_CONTEXT:名前でコンテキストを選択します。RSTREAM_ENGINE:Engine API 操作で使用するエンジン URL をオーバーライドします。RSTREAM_AUTHENTICATION_TOKEN:認証トークンをオーバーライドします。RSTREAM_MTLS_CERT_FILE:mTLS エージェント認証用のクライアント証明書ファイルです。RSTREAM_MTLS_KEY_FILE:mTLS エージェント認証用のクライアント秘密鍵ファイルです。RSTREAM_API_URL:コントロールプレーン API URL をオーバーライドします。RSTREAM_REGION:マネージドプロジェクトで許可されているリージョンを選択します。RSTREAM_CONTROL_PLANE_HEADERS:JSON オブジェクトとしてコントロールプレーンのリクエストヘッダーを追加します。
設定の解決動作は、config.NewClientFromEnv() と同じモデルに従います。まず明示的な SDK オプションが評価され、次に環境変数によるオーバーライド、最後に設定ファイルのコンテキスト/環境変数の値が評価されます。RSTREAM_CONFIG は、デフォルトの設定ファイルの場所にフォールバックする前に、設定ファイルのパスを指定します。トークン認証と mTLS エージェント認証は、コントロールチャネル接続では併用できません。mTLS 証明書と鍵の変数が設定されている場合、その接続では設定ファイル由来のトークンは使用されません。mTLS 変数と RSTREAM_AUTHENTICATION_TOKEN を同時に設定するとエラーになります。Engine HTTP API リクエストではトークンまたは証明書の ID が再利用されます。証明書クライアントは別個の mTLS オーソリティを検出します。
リージョンを選択するにはマネージドプロジェクトのエンドポイントが必要で、明示的なエンジンのオーバーライドとは併用できません。コントロールプレーンヘッダーは、追加のデプロイアクセスレイヤーを対象としています。認証、転送、およびホップバイホップの各ヘッダーは予約されています。不正な値や、大文字と小文字を区別しない重複は、ネットワーク I/O の前に拒否されます。
使用方法
基本的な HTTP トンネル
このコマンドを使用すると、デフォルトのプロトコルと公開設定でローカル HTTP サービスを公開できます。
# Create an HTTP tunnel for local port 8080 (default: HTTP protocol, published)
rstream forward 8080
このコマンドは公開 HTTP トンネルを作成し、転送先アドレス(例:https://abc123.rstream.io)を表示します。この URL に送信された HTTP リクエストはすべて localhost:8080 に転送されます。コマンドを停止するまで、トンネルは有効なままです。
ファイルを直接共有するには、rstream files ./exports または rstream files ./backup.tar.zst --password を実行します。このコマンドには、読み取り専用のブラウザー UI、WebDAV、中断後に再開できる個別ダウンロード、ディレクトリの ZIP 化機能が含まれています。--read-write を使用すると WebDAV API によるアップロードが有効になり、--no-ui を使用すると組み込みページが無効になります。アクセス ポリシー、フィルタリング、アップロード制限、CLI の完全なリファレンスについては、ファイル共有を参照してください。
TLS トンネル
公開するトンネルのエンドポイントで TLS を終端する必要がある場合は、--tls を使用してください。
# Create a secure TLS tunnel for local port 8080
rstream forward 8080 --tls
rstream ネットワーク経由でアクセスできる、安全な TLS 暗号化トンネルを作成します。標準の TLS クライアントは、トンネルの転送先アドレスに接続できます。
プライベートトンネル
rstream クライアントからのみ到達可能なプライベートトンネルを作成するには、--no-publish を使用してください。
# Create a private tunnel (not publicly accessible)
rstream forward 22 --tls --no-publish --name ssh-tunnel
プライベートトンネルへの接続には rstream クライアントが必要です。公開 URL ではなく、名前または ID で識別されます。
WebTTY リモートターミナル
rstream 経由でリモートシェルを公開するには、rstream webtty server -v --rstream を使用してください。rstream モードでは、WebTTY は標準の WebTTY ラベルを使用する公開 HTTP/WebSocket トンネルをデフォルトで作成します。代わりにプライベートトンネルを作成するには、--no-publish を追加してください。
# Start a published WebTTY server over rstream
rstream webtty server -v --rstream --name shell
# Start a private WebTTY server over rstream
rstream webtty server -v --rstream --name shell --no-publish
# Create and enroll a registered WebTTY server on this machine
rstream project use project-endpoint
rstream webtty server create prod-shell --enroll
# Start an enrolled registered WebTTY server over managed rstream WebTTY
rstream webtty server -v --server-id server_id
# If the server record is created from another machine, enroll on the runtime host
rstream project use project-endpoint
rstream webtty server create prod-shell
rstream webtty server enroll server_id
# Start a WebTTY daemon from an operator-managed runtime config
rstream webtty server -v --webtty-config /etc/rstream/webtty/prod-shell.yaml
# Start a local plain WebTTY server over TLS
rstream webtty server -v --transport plain --allow-unauthenticated --tls-cert-file server.crt --tls-key-file server.key
# Start a local WebTransport WebTTY server for a browser app
rstream webtty server -v --transport webtransport --allow-unauthenticated --allowed-origin http://127.0.0.1:3000 --tls-cert-file server.crt --tls-key-file server.key
# Create and show local WebTTY endpoint identities
rstream webtty identity create --name dev-shell
rstream webtty identity show --name dev-shell --endpoint-identity
rstream webtty identity create --name client-laptop
rstream webtty identity show --name client-laptop --endpoint-identity
rstream webtty identity list
# Authorize the client public endpoint identity on the server host
rstream webtty authorized-client add client-laptop --identity dev-shell --key client_endpoint_identity
rstream webtty authorized-client list --identity dev-shell
# Start a local WebTTY server that requires E2E and client proof
rstream webtty server -v --allow-unauthenticated --identity dev-shell
# Start a server that requires an explicit OS login identity
rstream webtty server -v --execution-mode login --login-user operator
# Connect through a standard websocket endpoint
rstream webtty client --url wss://example.rstream.io/ -- whoami
# Connect through the native rstream dialer using a tunnel name or ID
rstream webtty client --url rstrm://shell -- whoami
# Execute a command with JSON output for agents and scripts
rstream webtty exec --url rstrm://shell -- uname -a
# Execute through a locally known E2E WebTTY server endpoint identity
rstream webtty known-server add dev-shell --key server_endpoint_identity --client-identity client-laptop
rstream webtty known-server list
rstream webtty exec --url rstrm://dev-shell -- whoami
rstream webtty exec --url ws://127.0.0.1:8080 --known-server dev-shell -- whoami
# Expose a WebDAV filesystem sidecar rooted at $HOME
rstream webtty server -v --rstream --name shell --fs-root "$HOME"
# Read a file through the filesystem sidecar
rstream webtty fs read --url rstrm://shell /README.md
# List the available WebTTY servers
rstream webtty list
# Inspect managed WebTTY sessions and recorded events
rstream webtty sessions list
rstream webtty sessions show session_id
rstream webtty sessions events session_id
rstream webtty sessions export session_id --format text
rstream webtty sessions export session_id --format json --file session-export.json
rstream webtty sessions participants session_id
rstream webtty sessions join session_id
rstream webtty sessions join session_id --interactive --request-control
rstream webtty sessions control-requests session_id
# List workspaces, select a project, and enroll this CLI as a trusted device
rstream workspace list
rstream project use project-endpoint
rstream workspace device enroll --label ops-cli
rstream workspace device status
# Use advertised exec_path and fs_path values even when they match the defaults
# Register local rstream MCP tools for Codex
rstream codex setup
# Also start the configured server and verify the MCP handshake and tools
rstream codex setup --verify
# From Codex MCP, expose a service that is local to the remote WebTTY host
# rstream_remote_expose webtty_url=rstrm://shell port=8765 protocol=http
# For a direct authenticated-E2E WebTTY URL, also pass known_server=shell
# From Codex MCP, expose and discover a remote MCP surface on that host
# rstream_remote_expose webtty_url=rstrm://shell port=8765 mcp_path=/mcp labels=role=robot
# rstream_remote_mcp_discover
# Expose a local dev server through an MCP-managed local tunnel
# Available to Codex through rstream_local_tunnel_expose
rstream forward 3000 --name codex-local-tunnel --label role=codex
# Publish the local rstream MCP server over an HTTP tunnel
rstream mcp publish --name codex-rstream-mcp --label role=codex
# Open the live terminal UI for clients, tunnels, and WebTTY servers
rstream ui
rstream codex setup --verify は、新しく起動した MCP プロセスを必ず検証します。
開いている Codex タスクにすでに接続されている MCP プロセスは、起動時に使用された CLI バージョンで動作し続けます。署名済みの Homebrew バイナリを置き換えても、そのプロセス内のコードは置き換えられません。rstream CLI をアップグレードするたびに、新しい Codex タスクを開くか Codex を再読み込みしてから MCP を使用し、実際にツールを呼び出してください。コード署名はバイナリの ID と完全性を保護しますが、長時間稼働するプロセスは再起動しません。
rstream ui 内で c を押すと、コンテキストとプロジェクトの選択画面が開きます。設定済みのローカルコンテキストはすぐに利用でき、Control plane API にリンクされていないコンテキストも含まれます。アクティブな Control plane API のプロジェクトは、選択した認証情報でプロジェクトを検出できる場合、バックグラウンドで読み込まれます。1 と 2(または Tab)を使って、コンテキストとプロジェクトそれぞれのビューを切り替えます。各ビューには CURRENT 列と DEFAULT 列が明示され、選択した行の詳細パネルも表示されます。Enter を押すと、現在の UI プロセスでのみ切り替わります。d を押すと切り替えが行われ、選択したコンテキストがアクティブな rstream 設定ファイルのデフォルトとして保存されます。選択画面では / による検索と、r によるリモートプロジェクトの更新もできます。
プロジェクトの検出に失敗しても、ローカルコンテキストが非表示になったり無効になったりすることはありません。明示的な --api-url または RSTREAM_API_URL を指定すると、リンク済みコンテキストとリモートプロジェクトがその API の対象に限定されますが、リンクされていないコンテキストは引き続き選択できます。RSTREAM_ENGINE は引き続き強制的に適用されます。UI は、別のエンジンを対象とするコンテキストへの切り替えを拒否します。コンテキストを変更する前に、アクティブな WebTTY セッションを Ctrl+g q で閉じてください。
ログインの実行モードでは、パスワードは不要です。--login-user <username> は、すべてのリモートセッションの所有者となる既存の オペレーティングシステムのアカウント を指定します。rstream アカウントや、WebTTY クライアントから接続するユーザーを指定するものではありません。たとえば、--login-user alice を指定すると、ローカルの alice のホームディレクトリ、シェル、ID を使ってコマンドが実行されます。Linux または macOS では id -un を、Windows PowerShell では $env:USERNAME を実行すると、このオプションに渡すローカルのユーザー名を表示できます。rstream はアカウントを作成せず、設定したアカウントを特定できない場合、サーバーは起動を拒否します。Unix 系システムでは、別の OS ユーザーを選択すると、対象の uid、プライマリ gid、補足グループが適用されるため、WebTTY サーバープロセスにはそれに応じた権限が必要です。Windows では、--login-user にサーバーを実行しているものと同じ Windows アカウントを設定してください。別のアカウントへの切り替えやパスワードの使用には対応していません。
公開された WebTTY トンネルには、転送用の wss:// アドレスまたはネイティブの rstrm://<tunnel-id-or-name> 形式で接続できます。プライベートな WebTTY トンネルには、ネイティブの rstrm:// 形式でのみ接続できます。WebTTY サーバーは、ラベルを通じて機能、実行モード、エンドポイントのパスを通知します。コマンド実行には exec_path を使用し、現在のデフォルトは / です。オプションのファイルシステムサイドカーには fs_path を使用し、--fs-root を設定した場合の現在の値は /fs です。ファイルシステムのパスは、設定されたルートからの相対パスです。サーバーを --fs-root "$HOME/project" を付けて起動した場合、compose.yaml は /home/user/project/compose.yaml ではなく /compose.yaml として読み込みます。サイドカーは、設定されたルートの外を指すシンボリックリンクを拒否しますが、サンドボックスではなく、WebTTY サーバープロセスの権限をそのまま使用します。ファイルシステムサイドカーは独立した WebDAV のインターフェースであり、WebTTY の E2E ペイロード暗号化が有効な場合は拒否されます。
rstream webtty server -v --rstream で作成されたトンネル WebTTY サーバーは、標準の WebTTY インベントリラベルを持つ HTTP/WebSocket トンネル経路を使用します。登録済みの WebTTY サーバーは通常、ランタイムホスト上で rstream webtty server create <name> --enroll を使って作成・登録します。マシンを分けて構成する場合は、まずレコードを作成し、その後、ランタイムホストで rstream webtty server enroll <server-id> を実行します。生成されたローカルの登録情報は ~/.rstream/webtty/enrollments/<server-id>.yaml に保存されます。また、--server-id を付けて起動すると、protocol=webtty のトンネルが公開されます。登録情報には、コントロールプレーンのサーバー ID、プロジェクト ID、サーバー公開鍵のフィンガープリント、ローカルの ID ファイルのパス、サーバーの暗号化ポリシーが保存されます。登録には、ローカルで認証済みの rstream コンテキストが使用され、オペレーターのランタイム設定は使用されません。
ライブマネージドアタッチはエンジンによって調整されます。参加者リソースと制御リクエストリソースには HTTP 制御 API を使用し、その後、ターミナルストリームを WebTTY protobuf にアップグレードして Attach ハンドシェイクを行います。直接接続する WebTTY サーバーは新しい Open セッションのみを受け付け、マネージドアタッチのハンドシェイクは明確なプロトコルエラーで拒否します。CLI のライブアタッチでは、まずエンジンの機能ドキュメントを確認し、ターミナルストリームを開く前に、信頼済みワークスペースデバイスまたはローカル WebTTY ID グラントから E2E 復号マテリアルを解決します。
多数のフラグを指定する代わりに、YAML からデーモンを設定する場合は --webtty-config または RSTREAM_WEBTTY_CONFIG を使用してください。このランタイム設定はオペレーターが管理するもので、server.serverId を含めることができます。含まれている場合、CLI はマネージド WebTTY を公開する前に、そのサーバー ID 用に生成された登録情報を読み込みます。
version: 1
server:
serverId: srv_prod_shell_01
transport: websocket
executionMode: login
loginUser: operator
labels:
env: production
role: bastion
CLI フラグは --webtty-config の値を上書きし、--server-id を指定すると rstream マネージドモードが有効になります。server.serverEnrollment は、生成された登録情報がデフォルトの ~/.rstream/webtty/enrollments/<server-id>.yaml 以外のパスにある場合に限り、ランタイム設定で使用できます。
WebTTY E2E では、protobuf セッションエンベロープを表示したまま、stdin/stdout/stderr のペイロードバイトを暗号化します。サーバー ID はローカルホスト ID で、デフォルトでは ~/.rstream/webtty/identities/*.identity.json に保存され、ファイルモードは 0600 です。ワークスペースキーは別個のプロダクトキーであり、WebTTY ID ディレクトリではなく、ワークスペースキー階層に保存してください。明示的なサーバー ID マテリアル、既知のサーバーキー、またはポリシーで暗号化が必須とされている登録済みサーバーを指定すると、保護モードが有効になります。rstrm://... ターゲットの場合、クライアントはセッションを開く前にラベルとローカルの既知サーバーエントリーを解決できます。直接指定する ws://... ターゲットには、サーバーを直接信頼するためのマテリアルが必要です。ローカルの信頼ストアからピン留めされたサーバーを選択するには --known-server <name> を使用するか、自動化で信頼マテリアルを直接管理する場合は --known-server-key を渡します。--e2e は、コマンドで平文を拒否する必要がある場合にのみ、フェイルクローズを保証するアサーションとして使用します。
ローカル WebTTY ファイルは次の構成で配置します。
~/.rstream/webtty/identities/<name>.identity.json~/.rstream/webtty/enrollments/<server-id>.yaml~/.rstream/webtty/known_servers.json~/.rstream/workspaces/<workspace-id>/devices/<device-id>.json/etc/rstream/webtty/prod-shell.yamlなど、オペレーターが管理するデーモン設定
ID、登録情報、既知サーバー、ワークスペースデバイスの各ファイルは、POSIX システムでは権限 0600 で作成されます。グループまたは他のユーザーが読み取り可能な場合、実行時に拒否されます。
コンテナーや CI のデプロイでは、次の環境変数によるオーバーライドを使用できます。
RSTREAM_WEBTTY_CONFIG、RSTREAM_WEBTTY_AUTH_TOKEN、
RSTREAM_WEBTTY_IDENTITY、RSTREAM_WEBTTY_IDENTITY_FILE、
RSTREAM_WEBTTY_AUTHORIZED_CLIENT_KEYS、RSTREAM_WEBTTY_KNOWN_SERVER_KEY、
および RSTREAM_WEBTTY_KNOWN_SERVERS_FILE。
サーバー ID の優先順位は、インラインのエンドポイント ID JSON ドキュメントに使用する RSTREAM_WEBTTY_IDENTITY、次に --identity-file、次に --identity、次に RSTREAM_WEBTTY_IDENTITY_FILE、次に登録済みサーバーの登録 ID ファイル、最後に、--e2e を指定して明示的な ID なしで起動したアドホックサーバー用のデフォルト ~/.rstream/webtty/identities/default.identity.json の順です。E2E サーバーには、デフォルトの認可済みクライアントストア、--authorized-client-key、RSTREAM_WEBTTY_AUTHORIZED_CLIENT_KEYS、または明示的な認可済みクライアントファイルから取得した、認可済みクライアント署名キーが必要です。
クライアント ID の優先順位では、同じエンドポイント ID ソースを使用します。
RSTREAM_WEBTTY_IDENTITY、--identity-file、--identity、
RSTREAM_WEBTTY_IDENTITY_FILE、そして ~/.rstream/webtty/known_servers.json に
保存されたターゲットごとの client_identity の順です。認証済みの E2E クライアントは、
既定の ID を暗黙的に使用しません。クライアントの既知サーバー情報は、
--known-server、繰り返し指定する --known-server-key、
RSTREAM_WEBTTY_KNOWN_SERVER_KEY、--known-servers-file、または
RSTREAM_WEBTTY_KNOWN_SERVERS_FILE から取得します。キーの値には通常、
rstream webtty identity show --endpoint-identity で表示されるエンドポイント ID を
指定します。既定の既知サーバーストアは、解決済みの rstrm://... 接続を対象ごとに
管理します。解決済みのトンネルメタデータが利用できない場合、直接の ws://... 接続では
--known-server <name> または明示的な信頼情報を指定してください。
2 フィールドの暗号化専用形式は、特殊な暗号化専用インテグレーション向けに
下位レベルのヘルパーで引き続き受け付けますが、推奨される運用方法ではありません。
明示的な信頼済みサーバーキーが指定されていない場合は、既定の
~/.rstream/webtty/known_servers.json が読み込まれるため、クライアント側で追加の
フラグを指定しなくても E2E を判定できます。
ワークスペース管理の登録済みサーバーでは、ランタイムホストがすでに信頼済みの
ワークスペースデバイスである場合、サーバー登録時に公開ワークスペースキーセットの ID が
自動的にピン留めされます。後でローカルの信頼情報が変更された場合は、
rstream webtty server trust <server-id> でピン留めを更新してください。この修復コマンドにより、
ホストにワークスペースの秘密鍵をコピーせずに、リモートサーバーがワークスペース管理の
クライアント証明を検証できるようになります。
実装済みの E2E ヘルパースイートは、新しい 96 ビットノンスを使用した AES-256-GCM ペイロード暗号化と、
HPKE Base
DHKEM(X25519, HKDF-SHA256), HKDF-SHA256, AES-256-GCM キーエンベロープです。
Go WebTTY の tls:// プレーン転送とローカル WebTransport では、TLS 1.3 以上を使用します。
WebTTY の CLI、ローカルファイル、ランタイム設定、E2E ワークフローの完全なリファレンスについては、 docs/006-webtty.md を参照してください。
rstream mcp serve は、信頼済みのデバイス接続型 MCP サーフェスを stdio 経由で公開します。rstream codex setup は、そのサーバーを Codex 用にインストールし、rstream codex setup --verify は、ログインやネットワークアクセスなしで、範囲を限定した MCP 2025-11-25 ハンドシェイクを実行し、必須のローカルツールを確認します。
CLI サーフェスは、ワークステーションのコンテキスト、ローカルトンネル、WebTTY E2E ID と権限、ファイルシステムのサイドカー、リモートサービスの公開、リモート MCP ブリッジングを担当します。ホスト型の /api/mcp サーフェスは、OAuth のスコープが適用されたコントロールプレーンの自動化を担当し、デバイス専用の E2E 情報は意図的に使用できません。両者で共有されるツールは、同じ名前、タイトル、動作アノテーション、意味的な出力キー、オブジェクト形式の結果コントラクトを使用します。
rstream mcp publish は、デバイスサーフェスを /mcp で Streamable HTTP 経由で公開します。公開されたクライアントには、短期間有効でスコープが狭い rstream トークンが必要です。現在の全サーフェス公開と、シークレットを含む結果に関する制限は、最小権限の委任境界として扱えるようになる前に、明示的に追跡されています。
セットアップ、2 つのサーフェスのコントラクト、セキュリティ境界、検証、今後の強化作業については、docs/009-mcp.md を参照してください。
Netcat スタイルの TCP ストリームと rstream ストリーム
プレーンな TCP またはネイティブの rstream トンネルを介したバイトストリームセッションには、rstream netcat を使用します。このコマンドは rstream ncat および rstream nc としても利用できます。
# Connect to a plain TCP service
rstream nc 127.0.0.1:1234
# Expose a command over TCP
rstream nc -L 127.0.0.1:1234 -c "date"
# Expose a local SSH daemon through a private rstream tunnel
rstream nc -L rstrm://ssh-server -R 127.0.0.1:22
# Connect to that private rstream tunnel by name or ID
rstream nc rstrm://ssh-server
--listen で rstrm://[name] を指定すると、CLI は非公開の未公開バイトストリームトンネルを作成します。名前を指定しない場合は、起動時に生成されたトンネル識別子が出力され、別の rstream クライアントから接続できます。
非公開マシンに SSH 接続する場合は、通常、サーバー側のエントリーポイントとして rstream forward を使用する方が簡単です。ローカルの SSH デーモンにアクセスできるリモートマシンで起動します。
rstream forward 22 --bytestream --no-publish --name ssh-server
クライアントマシンでは、単発の SSH コマンドを使って経路を確認します。
ssh -o 'ProxyCommand rstream nc rstrm://ssh-server' admin@ssh-server hostname
通常の利用では、クライアント側の設定を SSH の ProxyCommand に移します。
Host ssh-server
HostName ssh-server
User admin
ProxyCommand rstream nc rstrm://%h
これによりトンネルは非公開のまま維持され、SSH は通常どおりホストキーの検証とユーザー認証を行います。
クライアントモードでは、--exec/--sh-exec でローカルコマンドを実行し、その標準入力/標準出力を接続にブリッジできます。これにより、シェルのパイプ処理を介さずに双方向の経路を確保できます。
rstream nc rstrm://ssh-server -c "my-local-client"
Netcat データグラムモード
rstream nc --datagram(-u)は、バイトストリームではなくパケットを転送します。データグラムモードでは、両側のエンドポイントに rstrm:// が必要です。--listen rstrm://[name] は非公開の未公開データグラムトンネルを作成し、rstream nc -u rstrm://<id-or-name> で接続します。データグラムモードでは --remote はサポートされません。
標準入力/標準出力はバイトストリームであるため、--framing で指定する明示的なフレーミングによって、標準入出力上のパケット境界を保持します。現在サポートされているフレーミングはデフォルトの rfc4571 のみです。これは RFC 4571 の定義に従い、各データグラムの先頭に 2 バイトのビッグエンディアン長を付加します。標準入出力上の 1 つのフレームはトンネル上の 1 つのデータグラムに対応するため、このフレーミングを読み書きするプログラムであれば、追加の調整なしにトンネル経由でパケットを送受信できます。
# Expose a datagram producer; one child process per accepted session
rstream nc -u -L rstrm://media -c "media-producer"
# Dial the tunnel; stdio carries RFC 4571 frames
rstream nc -u rstrm://media
# Or run a local consumer with bidirectional framed stdio
rstream nc -u rstrm://media -c "media-consumer" --idle-timeout 60s
データグラムトンネルでは、標準入出力の代わりにローカル UDP ソケットをブリッジすることもできます。これにより、フレーミングを気にせず UDP ネイティブのアプリケーションを接続できます。1 つの UDP パケットが 1 つのトンネルデータグラムに対応し、UDP エンドポイントには --framing は適用されません。
# Bridge tunnel sessions to a local UDP service (one connected socket per session)
rstream nc -u -L rstrm://media -R udp://127.0.0.1:5004
# Bind a local UDP socket and bridge it to a tunnel (one session per local peer)
rstream nc -u -L udp://127.0.0.1:5004 -R rstrm://media
# Receive-only local apps never send first; pin the peer to open the session eagerly
rstream nc -u -L udp://127.0.0.1:5004 -R rstrm://media --udp-peer 127.0.0.1:5006
CLI はトンネルの転送方式を自動選択する設定がデフォルトです。QUIC を優先し、UDP 経路が利用できない場合は TLS にフォールバックします。QUIC が選択されると、トンネル側のパケットは QUIC データグラム(RFC 9221)で転送される場合があります。輻輳制御は行われますが再送はされないため、配信は保証されません。また、各データグラムは経路 MTU の上限内に収める必要があります(標準入出力のフレームと UDP パケットのどちらも、ペイロードはおよそ 1200 バイトを安全な目安としてください)。サイズ超過のデータグラムは破棄され、セッションを終了することなくログに記録されます。パケット境界を損失なく保持する必要がある場合は、--datagram-guaranteed-delivery を使用してください。このモードでは、制御チャネルで QUIC が使われている場合でも、信頼性の高いストリームでパケットを転送します。
データグラムチャネルのどちらか一方を閉じると、相手側のセッションも閉じます。--idle-timeout は別の状況に対応するもので、指定した時間データグラムを受信しなかった場合にセッションを閉じます。受信パケットを想定する側でのみ使用してください。送信専用のプロデューサーは期限を更新するトラフィックを受信しないため、このオプションを設定してはいけません。データグラムの exec セッションでは、子プロセスの標準エラー出力は接続先ではなくローカルの標準エラー出力に送られます。標準エラー出力の生バイト列がフレーミングを破損させるためです。
UDP/データグラムトンネル
データグラム転送では、暗号化された UDP スタイルのトラフィックが必要な場合に DTLS モードを選択してください。
# Create a DTLS tunnel for UDP traffic on port 5000
rstream forward 5000 --dtls
DTLS トンネルはデータグラムトラフィックを自動的に処理します。--dtls を指定すると、--datagram フラグも暗黙的に有効になります。
実行(宣言型トンネル)
rstream run は、YAML ファイルまたは Docker ラベルに基づいてトンネルを同期し、必要に応じて監視や調整を行います。
forward:CLI 引数から単一のトンネルを作成し、直ちに転送を開始します(単一トンネル、対話型)。run --apply:YAML から宣言型のトンネル一覧を読み込み、監視や調整に対応します。run --docker:Docker ラベルからトンネルを検出し、監視や調整に対応します。
# Apply a YAML spec once
rstream -v run --apply examples/run-yaml/tunnels.yaml
# Watch the YAML for changes and reconcile
rstream -v run --apply examples/run-yaml/tunnels.yaml --watch
# Discover tunnels from Docker labels
rstream -v run --docker --watch
YAML スキーマ全体、Docker ラベルのリファレンス、調整の詳細については、docs/008-cmd-run.md を参照してください。
ビルドとコンパイル
rstream には、複数のプラットフォームとパッケージ形式に対応した包括的な Makefile が含まれています。
開発
日々の開発作業では、次のターゲットを使ってローカルの成果物をビルド、テスト、クリーンアップできます。
make # Build for current platform
make clean # Clean build artifacts
make tests # Run test suite
make examples # Build example applications
クロスプラットフォームコンパイル
複数のターゲット向けにバイナリを作成する場合は、次を使用します。
make cross # Build for all supported platforms
x86、ARM、MIPS、PowerPC、RISC-V など、複数のアーキテクチャにわたる Linux、macOS、Windows、BSD システムに対応しています。
パッケージング
リリースのパッケージングワークフローでは、次のターゲットを使ってアーカイブやプラットフォーム用パッケージをビルドできます。
make pkg # Create packages for current platform
make pkg-cross # Create packages for all platforms
make deb # Create Debian/Ubuntu packages
make docker # Build Docker images
make nupkg # Create Windows NuGet packages
コード例
Go SDK を使うと、アプリケーションからプログラムでトンネルを作成、管理できます。以下の例では config.NewClientFromEnv() を使い、CLI と同じ設定および環境変数を読み込みます。デフォルトコンテキスト(または RSTREAM_ENGINE)が設定されていることを確認し、選択したエージェント制御チャネルで認証が必要な場合は、RSTREAM_AUTHENTICATION_TOKEN または mTLS 証明書/キーの環境変数を指定してください。Engine HTTP API の操作では、自動検出による証明書認証もサポートされています。
管理対象の TURN 認証情報
SDK には、管理対象の TURN 認証情報を生成するヘルパーも用意されています。
Clientを 1 つ保持し、更新の際にclient.CreateTURNCredentials(ctx, options)を呼び出します。- 証明書クライアントは、メモリ内キャッシュを使って、検出された Engine API に直接アクセスします。
- 自動モードでは、中継メタデータが既知の場合、利用可能なローカル PAT/APP 導出を優先し、次に Control plane による発行を試み、利用可能な場合に限って Engine にフォールバックします。
- 明示的な
api、engine、pat、appモードに対応しています。管理対象の API にはいずれもturn.credentials.createが必要です。ローカルでの導出にはturn.relay.allocateが必要です。 config.CreateTURNCredentialsFromEnv(...)は、共通の設定サポートを引き続き利用します。
トランスポート、認可、有効期間、CLI の動作については、Engine HTTP mTLS and TURN を参照してください。
TURN ドメインは、ICE URL に配置される中継ホスト名です。TURN レルムは、認証情報の導出に使われる認証スコープです。グローバルエッジネットワークに接続されたリージョナル中継では、これらに異なる値を使用できます。コンテキスト解決では両方のフィールドを明示的に扱い、エンジンアドレスからレルムを推測することはありません。
package main
import (
"context"
"fmt"
"github.com/rstreamlabs/rstream-go/config"
)
func main() {
turn, err := config.CreateTURNCredentialsFromEnv(
context.Background(),
config.TURNCredentialsEnvOptions{},
)
if err != nil {
panic(err)
}
fmt.Println(turn.Username)
fmt.Println(turn.URLs)
}
明示的なクライアントオプション(例外)
設定と環境変数の解決を迂回する必要がある場合に限り、これを使用してください。
package main
import "github.com/rstreamlabs/rstream-go"
func main() {
client, err := rstream.NewClient(rstream.ClientOptions{
Engine: "engine.example:443",
Token: "authentication_token",
})
if err != nil {
panic(err)
}
_ = client
}
HTTP サーバー(公開トンネル)
この例では、公開 HTTP トンネルを作成し、トンネルリスナーを通じてリクエストを処理します。ForwardingAddress() が出力する転送先アドレスは、ブラウザーや curl から使用できる公開 URL です。
package main
import (
"context"
"fmt"
"net"
"net/http"
"github.com/rstreamlabs/rstream-go"
"github.com/rstreamlabs/rstream-go/config"
)
func main() {
client, err := config.NewClientFromEnv()
if err != nil {
panic(err)
}
ctrl, err := client.Connect(context.Background(), nil)
if err != nil {
panic(err)
}
defer ctrl.Close()
tunnel, err := ctrl.CreateTunnel(context.Background(), rstream.TunnelProperties{
Protocol: rstream.ProtocolPtr(rstream.ProtocolHTTP),
HTTPVersion: rstream.HTTPVersionPtr(rstream.HTTP1_1),
Publish: rstream.BoolPtr(true),
})
if err != nil {
panic(err)
}
defer tunnel.Close()
addr, _ := tunnel.ForwardingAddress()
fmt.Printf("Server accessible at: %s\n", addr)
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello from rstream!")
})
http.Serve(tunnel.(net.Listener), nil)
}
TLS エコー(プライベートトンネル)
この例では、プライベートトンネルのワークフローを示します。サーバーは echo という名前の非公開トンネルを作成し、トンネルへの受信接続を受け付けます。クライアントは名前を使ってプライベートトンネルにダイヤルし、確立されたストリームを通じてデータをやり取りします。
サーバーコード:
package main
import (
"context"
"io"
"log"
"net"
"github.com/rstreamlabs/rstream-go"
"github.com/rstreamlabs/rstream-go/config"
)
func main() {
client, err := config.NewClientFromEnv()
if err != nil {
panic(err)
}
ctrl, err := client.Connect(context.Background(), nil)
if err != nil {
panic(err)
}
defer ctrl.Close()
tunnel, err := ctrl.CreateTunnel(context.Background(), rstream.TunnelProperties{
Name: rstream.StringPtr("echo"),
Publish: rstream.BoolPtr(false),
})
if err != nil {
panic(err)
}
defer tunnel.Close()
props, err := tunnel.Properties()
if err != nil {
panic(err)
}
log.Printf("Echo server running as private tunnel: %s", *props.Name)
listener := tunnel.(net.Listener)
for {
conn, err := listener.Accept()
if err != nil {
break
}
go func(c net.Conn) {
defer c.Close()
log.Printf("New connection from %s", c.RemoteAddr())
io.Copy(c, c)
}(conn)
}
}
クライアントコード:
package main
import (
"context"
"fmt"
"github.com/rstreamlabs/rstream-go"
"github.com/rstreamlabs/rstream-go/config"
)
func main() {
client, err := config.NewClientFromEnv()
if err != nil {
panic(err)
}
conn, err := client.Dial(context.Background(), rstream.Addr{
IdOrName: "echo",
})
if err != nil {
panic(err)
}
defer conn.Close()
message := "Hello from private tunnel!"
conn.Write([]byte(message))
buffer := make([]byte, len(message))
conn.Read(buffer)
fmt.Printf("Sent: %s\nReceived: %s\n", message, string(buffer))
}
DTLS データグラムサーバー
この例では、公開 DTLS データグラムトンネルを作成します。転送先アドレスは、データグラムクライアントが接続する場所です。サーバーはパケットリスナー API を使ってデータグラムセッションを受け付け、パケットをエコーバックします。
package main
import (
"context"
"fmt"
"log"
"github.com/rstreamlabs/rstream-go"
"github.com/rstreamlabs/rstream-go/config"
)
func main() {
client, err := config.NewClientFromEnv()
if err != nil {
panic(err)
}
ctrl, err := client.Connect(context.Background(), nil)
if err != nil {
panic(err)
}
defer ctrl.Close()
tunnel, err := ctrl.CreateTunnel(context.Background(), rstream.TunnelProperties{
Name: rstream.StringPtr("dtls"),
Type: rstream.TunnelTypePtr(rstream.TunnelTypeDatagram),
Protocol: rstream.ProtocolPtr(rstream.ProtocolDTLS),
Publish: rstream.BoolPtr(true),
})
if err != nil {
panic(err)
}
defer tunnel.Close()
addr, _ := tunnel.ForwardingAddress()
fmt.Printf("DTLS server accessible at: %s\n", addr)
packetListener := tunnel.(rstream.PacketListener)
for {
conn, _, err := packetListener.Accept()
if err != nil {
log.Printf("Accept error: %v", err)
continue
}
go func() {
defer conn.Close()
buffer := make([]byte, 1024)
for {
n, addr, err := conn.ReadFrom(buffer)
if err != nil {
break
}
log.Printf("Received %d bytes from %s", n, addr)
n, err = conn.WriteTo(buffer[:n], addr)
if err != nil {
break
}
}
}()
}
}
QUIC サーバー
この例では、公開 QUIC データグラムトンネルを作成します。QUIC は、低レイテンシとネットワーク変更への耐性を目的に設計された最新のトランスポートです。このサンプルでは、ローカルの TLS 設定を生成し、トンネルのパケットリスナーを通じて QUIC ストリームを提供します。
package main
import (
"context"
"crypto/rand"
"crypto/rsa"
"crypto/tls"
"crypto/x509"
"encoding/pem"
"fmt"
"log"
"math/big"
"github.com/quic-go/quic-go"
"github.com/rstreamlabs/rstream-go"
"github.com/rstreamlabs/rstream-go/config"
)
func generateTLSConfig() (*tls.Config, error) {
key, err := rsa.GenerateKey(rand.Reader, 1024)
if err != nil {
return nil, err
}
template := x509.Certificate{SerialNumber: big.NewInt(1)}
certDER, err := x509.CreateCertificate(rand.Reader, &template, &template, &key.PublicKey, key)
if err != nil {
return nil, err
}
keyPEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(key)})
certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certDER})
tlsCert, err := tls.X509KeyPair(certPEM, keyPEM)
if err != nil {
return nil, err
}
return &tls.Config{
Certificates: []tls.Certificate{tlsCert},
}, nil
}
func main() {
client, err := config.NewClientFromEnv()
if err != nil {
panic(err)
}
ctrl, err := client.Connect(context.Background(), nil)
if err != nil {
panic(err)
}
defer ctrl.Close()
tunnel, err := ctrl.CreateTunnel(context.Background(), rstream.TunnelProperties{
Name: rstream.StringPtr("quic"),
Type: rstream.TunnelTypePtr(rstream.TunnelTypeDatagram),
Protocol: rstream.ProtocolPtr(rstream.ProtocolQUIC),
Publish: rstream.BoolPtr(true),
})
if err != nil {
panic(err)
}
defer tunnel.Close()
addr, _ := tunnel.ForwardingAddress()
fmt.Printf("QUIC server accessible at: %s\n", addr)
tlsCfg, err := generateTLSConfig()
if err != nil {
panic(err)
}
transport := quic.Transport{
Conn: rstream.PacketConnFromPacketListener(tunnel.(rstream.PacketListener)),
}
listener, err := transport.Listen(tlsCfg, nil)
defer listener.Close()
for {
conn, err := listener.Accept(context.Background())
if err != nil {
log.Printf("Accept error: %v", err)
continue
}
go func() {
defer conn.CloseWithError(0, "server done")
stream, err := conn.AcceptStream(context.Background())
if err != nil {
return
}
defer stream.Close()
buffer := make([]byte, 1024)
for {
n, err := stream.Read(buffer)
if err != nil {
break
}
log.Printf("Received %d bytes from %s", n, conn.RemoteAddr())
n, err = stream.Write(buffer[:n])
if err != nil {
break
}
}
}()
}
}
参考資料
- ドキュメント:https://rstream.io/docs
- Go SDK(リファレンス実装):https://github.com/rstreamlabs/rstream-go
- C++ SDK:https://github.com/rstreamlabs/rstream-cpp
運用および高度な CLI/SDK ワークフロー:
- CLI ワークフローと認証:docs/001-cli-workflow.md
- 宣言型の実行ワークフロー:docs/008-cmd-run.md
- トランスポート設定:docs/002-transport.md
- トンネルプロパティのリファレンス:docs/003-tunnel-properties.md
コントリビューション
プルリクエストを歓迎しています。バグの修正、機能の追加、ドキュメントの改善、拡張機能の提案など、皆さんの貢献によって rstream はより良いものになります。ローカルでビルドし、チェックを実行して、検証内容を明記した焦点の定まったプルリクエストを提出してください。このリポジトリ固有のコントリビューションガイドラインについては、CONTRIBUTING.md をご覧ください。
サポート
サポートを受ける:
[email protected]
セキュリティに関する懸念を報告する:
[email protected]
このリポジトリで採用しているセキュリティ報告のガイドラインについては、SECURITY.md をご覧ください。
ライセンス
このリポジトリは Apache License 2.0 の下でライセンスされています。LICENSE をご覧ください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。