no-crd について
no-crd は、AI エージェントやプラットフォームチーム向けの MCP サーバー兼 TypeScript SDK で、CRD やクラスタオペレーターなしで Kubernetes 上の一時的なコンテナワークスペースを作成、ルーティング、管理できます。複数の JavaScript ランタイムに対応し、テンプレートによる Pod 構成と実験的なルーティングプロキシを備えています。
主な機能
- 01Kubernetes Pod の作成と管理
- 02テンプレートによるワークスペース構成
- 03稼働中のワークスペースへの通信ルーティング
- 04Node.js、Bun、Deno に対応
- 05Pod 管理用 Web UI を内蔵
活用シーン
- 01AI エージェント用の一時サンドボックス作成
- 02標準的な Kubernetes クラスタ上の Pod 管理
- 03稼働中のコンテナワークスペースへの通信転送
MCP 対応
MCP クライアントに Kubernetes Pod とワークスペースの管理機能を提供します。HTTP/SSE と stdio のトランスポートに対応します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
npx -y @nogoo9/no-crdKUBECONFIGPath to the Kubernetes API credentials configuration fileBASE_URLHosting URL subpath prefix for gateways and reverse proxiesSTATELESSDisable in-memory session tracking for stateless executionTLS_CERTLocal file path containing TLS public certificate (HTTPS)TLS_KEYシークレットLocal file path containing TLS private key (HTTPS)TLS_CALocal file path containing trusted client Certificate AuthorityNODE_TLS_REJECT_UNAUTHORIZEDシークレットSet to '0' to allow connection to unverified TLS endpointsREGISTRY_URLDefault container registry for workspace image resolutionTEMPLATES_DIRLocal filesystem directory containing custom YAML/JSON templatesBUILTIN_TEMPLATESEnable loading of standard pre-configured templates (default: true)AUTH_ENABLEDシークレットEnforce JWT verification and user tenant isolation (default: false)JWT_VERIFICATION_REQUIREDSet to 'false' to skip OIDC cryptographic signature checksJWT_SECRETシークレットHMAC-SHA symmetric secret key to sign/verify JWT tokensJWT_PUBLIC_KEYシークレットPEM public key to verify asymmetric OIDC signaturesJWKS_URIDiscovery URI to fetch keys from OIDC provider dynamicallyINTROSPECTION_ENDPOINTRFC 7662 compliant token introspection validation endpointOAUTH_CLIENT_IDシークレットClient identifier for OAuth2 authentication flowsOAUTH_CLIENT_SECRETシークレットClient secret credentials used for token introspectionJWT_AUDIENCETarget audience check value for incoming OIDC tokensAUTH_ISSUERシークレットExpected token issuer authority check value (e.g. Keycloak)AUTH_SUB_JSONPATHシークレットJSONPath pattern to extract user identity subject from tokenAUTH_ADMIN_ROLEシークレットBypass role name that grants admin access (default: nogoo9-admin)AUTH_ADMIN_USERSシークレットComma-separated list of user subject IDs (sub) granted admin privileges without OIDC scope/role claimsPROXY_SESSION_TTLActive lifetime in seconds for signed proxy session cookiesPROXY_SESSION_SECRETシークレットSecret key for session cookie signingUI_ENABLEDServe the built-in HTML dashboard (default: true)THEMES_DIRFilesystem directory to scan for custom CSS themesTHEMES_CONFIGMAPConfigMap name storing dynamic CSS theme overridesDOCS_DIRDirectory containing static documentation web files to serveOAUTH_DISCOVERY_URLシークレットStandard OIDC .well-known configuration discovery endpointOAUTH_LOGIN_METHODシークレットUI SSO flow login method: 'redirect' or silent 'iframe'UI_TITLECustom dashboard header title for white-label brandingUI_SUBTITLECustom dashboard subtitle text below the header titleローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
@nogoo9/no-crd
エージェント主導のオンデマンドな Kubernetes Pod オーケストレーション — カスタムリソース定義は不要です。
@nogoo9/no-crd は、軽量で複数のランタイムに対応した Model Context Protocol(MCP)サーバーです。AI エージェントや API が、標準的な Kubernetes(k8s/k3s)クラスター上で、一時的なコンテナ化サンドボックスを動的に起動し、接続先を振り分け、管理できるようにします。カスタムリソース定義(CRD)や、クラスター単位のオペレーター、昇格された RBAC 権限は必要ありません。
JupyterHub のような動的な Pod ライフサイクル管理を提供しながら、実際のワークロードには一切依存せず、Bun、Deno、Node.js での複数ランタイム実行に対応しています。
📚 詳しいガイド、API リファレンス、設定オプションについては、公開されているドキュメントサイトをご覧ください。または、サーバーの実行中に /docs/(例:http://localhost:3000/docs/)で提供される組み込みドキュメントをご利用ください。
🗺️ 利用目的に合わせて選択
@nogoo9/no-crd を使い始めるには、目的に合ったトラックを選択してください。
- トラック A:AI エージェントおよび MCP ユーザー $\rightarrow$ MCP クライアント設定ガイド
- 最適な用途:
no-crdを Cursor、Claude Desktop、Cline、または Roo Code に接続して、エージェントがポッドを管理できるようにします。
- 最適な用途:
- トラック B:プラットフォームおよびサービスのデプロイ担当者 $\rightarrow$ SSO とルーティングのデプロイガイド
- 最適な用途: Keycloak OIDC、ステートレス Cookie、リバースプロキシルーティングを使用して、Kubernetes クラスターにマルチテナントのサンドボックスサービスをデプロイします。
- トラック C:SDK およびコードのコントリビューター $\rightarrow$ SDK とコントリビューターガイド
- 最適な用途: TypeScript SDK を使用してプログラムからポッドを制御するか、コアランタイムコードベースに貢献します。
🚀 主な機能
- CRD 不要: コア Kubernetes リソース(Pods、ConfigMaps、ServiceAccounts)に対して直接実行します。高い移植性、安全性を備え、制限付き/マネージド環境(EKS、GKE、K3s)と互換性があります。
- エージェントサンドボックスの起動: コンテキスト検証、初期化コンテナー、IAM ロール、停止前フック、ライフサイクル同期を使用してワークスペースのプロビジョニングを自動化する、専用の起動ツールです。
- ConfigMap ベースのテンプレート: 再利用可能なポッドテンプレートを標準的な Kubernetes ConfigMaps として保存、バージョン管理、読み込みできます。
- ローカルファイルシステムテンプレート: YAML/JSON のポッドテンプレートを Docker イメージに組み込むか、ホストパスからマウントできます。パッケージには組み込みのデフォルト設定が含まれています。
- アイソモーフィックなマルチランタイム SDK: Node.js、Bun、または Deno 上で動作する、合成可能なプログラム用 SDK または MCP サーバーとしてシームレスにインポートできます。
- ワークスペースルーティングプロキシ(試験運用): 実行中のコンテナー IP にトラフィックを動的に転送する組み込みのリバースプロキシルーティング機能です。ユーザートークンの所有権を安全に検証し、パススコープ付きセッション Cookie(
nocr_tokenとnocr_sess)を使用します。短期間のトークンの有効性を保つため、HMAC 署名付きセッション管理も自動で行います。 - JWT 認証(試験運用): HS256、RS256、ES256、JWKS エンドポイント、OAuth 2.0 トークンイントロスペクション(RFC 7662)に対応する、組み込みの OAuth トークン検証エンジンです。
- 組み込み Web UI アプリ: ライト/ダークテーマの切り替え、クライアント側の PKCE OIDC ログインとプロアクティブなサイレントトークン更新、ワークスペースファイルのプレビュー表示(HTML のサンドボックス化された iframe とカスタム Markdown レンダリングに対応)を備えた、インタラクティブな Web ベースの Pod Manager インターフェイスを提供します。
⚡ クイックスタート
NPX で単独実行(インストール不要)
# Option 1: Start HTTP/SSE server on port 3000
npx @nogoo9/no-crd --transport http --port 3000
# Option 2: Run over standard input/output (stdio) for local IDE agents
npx @nogoo9/no-crd --transport stdio --mode cluster
グローバルにインストール
npm install -g @nogoo9/no-crd
nocrd9 --transport stdio --mode cluster
Docker で実行
docker run -d -p 3000:3000 \
-v "$HOME/.kube/config:/app/.kube/config:ro" \
-e KUBECONFIG=/app/.kube/config \
ghcr.io/nogoo9/no-crd:latest
⚙️ 設定と環境変数
サーバーとコマンドラインユーティリティは、CLI オプションまたは環境変数で設定できます。以下にすべての設定項目のクイックリファレンスを示します。
🔌 サーバー設定
| CLI オプション | 環境変数 | デフォルト | 許可される値 | 説明 |
|---|---|---|---|---|
-t, --transport | TRANSPORT | http | http, stdio, both | サーバーのトランスポートモードです。both を指定すると、両方のトランスポートを同時に起動します。 |
-p, --port | PORT | 3000 | 数値 | SSE トランスポート用の HTTP サーバーポートです。 |
-H, --host | HOST | 0.0.0.0 | 文字列 | HTTP/SSE サーバーをバインドするホストインターフェースです。 |
--base-url | BASE_URL | "" | パス文字列 | リバースプロキシの背後でホストする場合のベース URL パスプレフィックスです(例:/gateway/no-crd)。 |
| - | STATELESS | false | true, false | ステートレスなリクエスト処理(セッションアフィニティなし)を有効にします。 |
-l, --log-level | LOG_LEVEL | info | debug, info, warning, error, fatal | ログの詳細度を指定します。 |
| - | LOG_FILE | nogoo9-mcp.log | 文字列 | ファイルロギングの出力先ファイルパスです。 |
| - | RATE_LIMIT_MAX | 100 | 数値 | レート制限対象のルートで、期間ごとに許可されるリクエストの最大数です。 |
| - | RATE_LIMIT_WINDOW | 60000 | 数値 | レート制限対象のルートにおける期間の長さをミリ秒で指定します。 |
--proxy-timeout | PROXY_TIMEOUT | 120000 | 数値 | ルーティングプロキシのアップストリームリクエストのタイムアウトをミリ秒で指定します。 |
--proxy-keep-alive | PROXY_KEEP_ALIVE | true | true, false | ルーティングプロキシのアップストリームリクエストで TCP キープアライブを有効にします。 |
🔒 TLS 設定
| CLI オプション | 環境変数 | デフォルト | 許可される値 | 説明 |
|---|---|---|---|---|
--tls-cert | TLS_CERT | - | パス文字列 | HTTPS を有効にする TLS 証明書ファイルのパスです。 |
--tls-key | TLS_KEY | - | パス文字列 | HTTPS を有効にする TLS 秘密鍵ファイルのパスです。 |
--tls-ca | TLS_CA | - | パス文字列 | HTTPS クライアントの認証/検証用 TLS CA 証明書ファイルのパスです。 |
| - | NODE_TLS_REJECT_UNAUTHORIZED | true | 0 (false), 1 (true) | 0 に設定すると、TLS 検証を回避します(開発/テスト専用)。 |
🌐 CORS 設定
| CLI オプション | 環境変数 | デフォルト | 許可される値 | 説明 |
|---|---|---|---|---|
--cors-origin | CORS_ALLOWED_ORIGIN, CORS_ORIGIN | * | 文字列 | CORS の Allowed Origin ヘッダーです。 |
--cors-methods | CORS_ALLOWED_METHODS, CORS_METHODS | GET, POST, OPTIONS | 文字列 | CORS の Allowed Methods ヘッダーです。 |
--cors-headers | CORS_ALLOWED_HEADERS, CORS_HEADERS | Content-Type, Authorization, mcp-protocol-version, mcp-session-id | 文字列 | CORS の Allowed Headers ヘッダーです。 |
--cors-allow-credentials | CORS_ALLOW_CREDENTIALS, CORS_CREDENTIALS | false | true, false | CORS の Access-Control-Allow-Credentials ヘッダーを有効にします。 |
--cors-expose-headers | CORS_EXPOSED_HEADERS, CORS_EXPOSED | mcp-session-id, x-refreshed-token | 文字列 | カスタム CORS Access-Control-Expose-Headers ヘッダーです。 |
--cors-max-age | CORS_MAX_AGE | - | 数値 | カスタム CORS Access-Control-Max-Age ヘッダーの秒数です。 |
☸️ Kubernetes の設定
| CLI オプション | 環境変数 | デフォルト | 許可される値 | 説明 |
|---|---|---|---|---|
-m, --mode | MODE | cluster | cluster、namespaced | Kubernetes へのアクセス範囲です。namespaced は、操作を単一の名前空間に限定します。 |
-n, --namespace | NAMESPACE, DEFAULT_NAMESPACE | nogoo9 | 文字列 | 操作に使用するデフォルトの Kubernetes 名前空間です。 |
--disable-permission-checks | DISABLE_PERMISSION_CHECKS | false | true、false | Kubernetes RBAC の権限チェックを無効にし、すべてのツールが有効であるものとして扱います。 |
--managed-only | MANAGED_ONLY | true | true、false | true の場合、Pod ツールはこのサーバーが管理する Pod(nogoo9/managed-by ラベルが付いたもの)のみを操作します。管理者を含め、これを回避することはできません。ADR-008 を参照してください。 |
--default-workspace-port | DEFAULT_WORKSPACE_PORT | - | 数値 | トラフィックのプロキシ先となる、ワークスペースの Pod 内のデフォルトのターゲットポートです。 |
| - | REGISTRY_URL | - | URL 文字列 | イメージを検索する対象のコンテナーレジストリ URL です(例:http://localhost:5001)。 |
| - | TEMPLATES_DIR | - | パス文字列 | Pod テンプレートファイル(YAML/JSON)を含むローカルディレクトリのパスです。ADR-001 を参照してください。 |
| - | BUILTIN_TEMPLATES | true | true、false | パッケージに同梱されている組み込みテンプレートを無効にするには、false に設定します。 |
🔑 認証の設定
| CLI オプション | 環境変数 | デフォルト値 | 許容値 | 説明 |
|---|---|---|---|---|
--auth-enabled | AUTH_ENABLED | false | true, false | MCP ツールとルートプロキシで JWT トークン認証を有効にします。 |
| - | JWT_VERIFICATION_REQUIRED | true | true, false | JWT 署名検証(署名チェック)を有効または無効にします。 |
| - | JWT_SECRET | - | 文字列 | トークン検証に使用する対称 HMAC-SHA256 シークレットです。 |
| - | JWT_PUBLIC_KEY | - | 文字列 | 非対称トークン検証に使用する PEM エンコード済み RSA/ECDSA 公開鍵です。 |
| - | JWKS_URI | - | URL 文字列 | 検証鍵を動的に取得するためのリモート JWKS エンドポイント URL です。 |
| - | INTROSPECTION_ENDPOINT, JWT_INTROSPECTION_ENDPOINT | - | URL 文字列 | トークンのイントロスペクション/検証用エンドポイントです。 |
| - | OAUTH_CLIENT_ID | - | 文字列 | 認証設定用の OAuth クライアント ID です。 |
| - | OAUTH_CLIENT_SECRET | - | 文字列 | 認証設定用の OAuth クライアントシークレットです。 |
| - | JWT_AUDIENCE | - | 文字列 | 想定されるトークンのオーディエンスです。設定されている場合は OAUTH_CLIENT_ID がフォールバックとして使用されます。 |
| - | AUTH_ISSUER, JWT_ISSUER | "" | URL 文字列 | メタデータディスカバリーで通知される認可サーバーの識別 URL です。 |
| - | AUTH_SUB_JSONPATH | $.sub | JSONPath | JWT ペイロードから一意のユーザー ID を抽出するペイロードパスです。 |
--auth-scope-jsonpath | AUTH_SCOPE_JSONPATH | $.scope | JSONPath | JWT ペイロードからスコープクレームを抽出するペイロードパスです。 |
--auth-roles-jsonpath | AUTH_ROLES_JSONPATH, AUTH_ADMIN_JSONPATH | $.realm_access.roles | JSONPath | JWT ペイロードからユーザーロールを抽出するペイロードパスです。 |
| - | AUTH_ADMIN_ROLE | admin | 文字列 | 管理者アクセスを示すロール名です。 |
--auth-required-read-scope | AUTH_REQUIRED_READ_SCOPE | nogoo9:read | 文字列 | 読み取り操作に必要な OAuth スコープです。設定されていない場合、読み取りスコープのチェックは省略されます。 |
--auth-required-write-scope | AUTH_REQUIRED_WRITE_SCOPE | nogoo9:write | 文字列 | 書き込み/変更操作に必要な OAuth スコープです。設定されていない場合、書き込みスコープのチェックは省略されます。 |
--auth-required-admin-scope | AUTH_REQUIRED_ADMIN_SCOPE | nogoo9:admin | 文字列 | 管理者操作に必要な OAuth スコープです。設定されていない場合、管理者スコープのチェックは省略されます。 |
| - | AUTH_ADMIN_USERS | `` | ユーザーのサブジェクト ID(sub)のカンマ区切りリスト | OIDC のスコープ/ロールクレームがなくても管理者権限を付与するユーザーのサブジェクト ID(sub)のカンマ区切りリストです(回避策としてのフォールバック)。 |
--auth-required-read-role | AUTH_REQUIRED_READ_ROLE | viewer | 文字列 | 読み取り操作に必要なユーザーロールです。設定されていない場合、読み取りロールのチェックは省略されます。 |
--auth-required-write-role | AUTH_REQUIRED_WRITE_ROLE | user | 文字列 | 書き込み/変更操作に必要なユーザーロールです。設定されていない場合、書き込みロールのチェックは省略されます。 |
| - | PROXY_SESSION_TTL | 1800 | 数値 | セッション Cookie の有効期限(秒単位)です(スライディングウィンドウの期間)。 |
| - | PROXY_REFRESH_COOKIE_TTL | 604800 | 数値 | 暗号化されたリフレッシュトークン Cookie(nocr_refresh)のデフォルトの Max-Age です。IdP の refresh_expires_in が利用可能な場合は、その値で上書きされます。 |
| - | PROXY_TOKEN_COOKIE_TTL | 86400 | 数値 | アクセストークン Cookie(nocr_token)のデフォルトの Max-Age です。JWT の exp クレームが利用可能な場合は、その値で上書きされます。 |
| - | PROXY_SESSION_SECRET | "" | 文字列 | ステートレスセッション Cookie の署名に使用する HMAC シークレットキーです。設定されていない場合は JWT_SECRET がフォールバックとして使用されます。 |
| - | OAUTH_SCOPES | openid profile email offline_access | スペース区切りのスコープ文字列 | 認可時に要求する OAuth スコープです。リフレッシュトークンを使用する場合は 'offline_access' を含めてください。 |
| - | OAUTH_AUTHORIZATION_URL | - | URL 文字列 | OAuth 認可 URL を直接指定します。 |
| - | OAUTH_SERVER_DISCOVERY_URL, OAUTH_DISCOVERY_URL | - | URL 文字列 | バックエンドゲートウェイが使用する OAuth サーバーのディスカバリー URL です。OAUTH_DISCOVERY_URL がフォールバックとして使用されます。 |
| - | OAUTH_TOKEN_URL, OAUTH_SERVER_TOKEN_URL | - | URL 文字列 | バックエンドサーバーの OAuth トークン交換エンドポイントを直接指定します。 |
| - | OAUTH_END_SESSION_URL | - | URL 文字列 | OAuth ログアウトエンドポイントを直接指定します。 |
--auth-inject-workspace-jwt | AUTH_INJECT_WORKSPACE_JWT | true | true, false | 生のトークンを含むカスタムの 'x-workspace-jwt' ヘッダーをプロキシリクエストに挿入するかどうかを指定します。 |
| - | AUTH_DEFAULT_ROLE | viewer | 文字列 | トークンにスコープ/ロールが含まれていない場合のフォールバックロールです。 |
--max-workspaces-per-user | MAX_WORKSPACES_PER_USER | 0 | 数値 | 管理者以外のユーザーが所有できる、同時にアクティブなワークスペースの最大数です(0 は無制限)。 |
🖥️ UI とテーマの設定
| CLI オプション | 環境変数 | デフォルト | 許可される値 | 説明 |
|---|---|---|---|---|
| - | UI_ENABLED | true | true、false | 埋め込み HTML Pod Manager UI リソースを有効にします。 |
| - | THEMES_DIR | themes | パス文字列 | カスタム CSS UI テーマを含むローカルディレクトリのパスです。 |
| - | THEMES_CONFIGMAP | - | 文字列 | カスタム UI テーマ設定を含む Kubernetes ConfigMap の名前です。 |
| - | DOCS_DIR | /app/docs (Docker) or docs/.vitepress/dist (Local) | パス文字列 | 静的ドキュメントファイルを配信する基準ディレクトリです。 |
| - | OAUTH_DISCOVERY_URL | "" | URL 文字列 | UI クライアントが使用する OAuth 認可サーバーのディスカバリー URL です。 |
| - | OAUTH_CLIENT_ID | "" | 文字列 | UI 認証用の OAuth クライアント ID です。 |
| - | OAUTH_LOGIN_METHOD | redirect | redirect、popup | UI OAuth クライアントのログイン操作モードです。 |
| - | UI_TITLE | nogoo9 Pod Manager | 文字列 | ダッシュボードのヘッダーに表示するカスタムタイトルです。 |
| - | UI_SUBTITLE | On-demand Kubernetes pod orchestration and agent-sandbox management without CRDs. | 文字列 | ダッシュボードタイトルの下に表示するカスタムサブタイトルです。 |
☸️ Kubernetes のセットアップと RBAC 権限
@nogoo9/no-crd MCP サーバーが Kubernetes と連携するには、適切な RBAC 権限で実行する必要があります。設定に応じて、**クラスター全体(ClusterRole)へのアクセス、または名前空間スコープ(Role)**のアクセスを許可してデプロイできます。
ツールと権限の対応関係
以下に、各 MCP ツールが必要とする Kubernetes API リソースと動詞の対応を示します。サーバーは起動時にこれらの権限を動的に確認し(SelfSubjectAccessReview 経由)、現在の ID に使用が許可されているツールのみを登録します。
リソース:configmaps
| 必要な動詞 | 関連する MCP ツール | 説明/目的 |
|---|---|---|
create | create_template | 新しい Pod テンプレート定義を ConfigMap として保存します。 |
delete | delete_template | 保存済みの Pod テンプレート ConfigMap を削除します。 |
get | create_pod_from_template | ConfigMap に保存されたテンプレートの Pod 仕様を読み取ります。 |
update | update_template | 既存のテンプレートのメタデータ、アノテーション、または仕様を変更します。 |
リソース:events
| 必要な動詞 | 関連する MCP ツール | 説明/目的 |
|---|---|---|
list | get_workspace_events |
リソース:namespaces
| 必要な動詞 | 関連する MCP ツール | 説明/目的 |
|---|---|---|
list | list_namespaces | クラスター内の名前空間を検出します(クラスターアクセスモードでのみ必要です)。 |
リソース:pods
| 必要な動詞 | 関連する MCP ツール | 説明/目的 |
|---|---|---|
create | create_pod、create_pod_from_template、spawn_workspace、upgrade_all_workspaces、upgrade_workspace | 新しい Pod またはワークスペースサンドボックスをプロビジョニングしてデプロイします。 |
delete | delete_pod、stop_workspace、upgrade_all_workspaces、upgrade_workspace | Pod またはワークスペースサンドボックスを終了してクリーンアップします。 |
get | get_pod、get_workspace、upgrade_workspace | 特定の Pod の詳細な JSON 仕様を取得します。 |
list | list_pods、list_workspaces、upgrade_all_workspaces | Pod またはエージェントのワークスペース Pod の一覧を取得します。 |
patch | patch_pod | ラベル、アノテーション、またはリソースの要求/上限を戦略的マージパッチで更新します。 |
リソース:pods/log
| 必要な動詞 | 関連する MCP ツール | 説明/目的 |
|---|---|---|
get | get_pod_logs | Pod コンテナーの標準出力/標準エラーログを取得します。 |
1. クラスター全体モード(MODE=cluster)
クラスター内の任意の名前空間にわたって MCP サーバーにサンドボックスを管理させる場合は、このモードを使用します。
ClusterRole と ClusterRoleBinding を作成します。
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: nogoo-mcp
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch", "create", "delete", "patch", "update"]
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get"]
- apiGroups: [""]
resources: ["namespaces"]
verbs: ["get", "list"]
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "list", "create", "update", "patch", "delete"]
- apiGroups: [""]
resources: ["serviceaccounts"]
verbs: ["get", "list", "create", "update", "patch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: nogoo-mcp
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: nogoo-mcp
subjects:
- kind: ServiceAccount
name: nogoo-mcp
namespace: nogoo9 # Change to the namespace where your MCP server runs
2. 名前空間スコープモード(MODE=namespaced)
MCP サーバーを単一の名前空間(例:nogoo9)に制限する場合は、このモードを使用します。このモードでは、クラスター全体や管理者向けの権限は必要ありません。
対象の名前空間に Role と RoleBinding を作成します。
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: nogoo-mcp
namespace: nogoo9
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch", "create", "delete", "patch", "update"]
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get"]
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "list", "create", "update", "patch", "delete"]
- apiGroups: [""]
resources: ["serviceaccounts"]
verbs: ["get", "list", "create", "update", "patch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: nogoo-mcp
namespace: nogoo9
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: nogoo-mcp
subjects:
- kind: ServiceAccount
name: nogoo-mcp
namespace: nogoo9
(注:名前空間スコープモードでは、list_namespaces ツールは対象の名前空間のみを返し、すべてのツールで名前空間パラメーターの入力値は対象の名前空間がデフォルトになります。)
📑 ワークスペーステンプレートとスポーナーのアノテーション
@nogoo9/no-crd のテンプレートは、以下の3つのソースから読み込めます(優先度の高い順)。
- Kubernetes ConfigMap —
nogoo9/pod-template: "true"ラベルが付いたもの(従来の方式) - カスタムローカルディレクトリ —
TEMPLATES_DIR環境変数で指定(YAML または JSON ファイル) - 組み込みテンプレート — npm パッケージに同梱(
BUILTIN_TEMPLATES=falseで無効化)
形式の詳細については、ADR-001 を参照してください。
1. テンプレートの定義方法
スポーナーにテンプレートを登録するには、以下の要件を満たす ConfigMap を作成します。
- 検出ラベル:
nogoo9/pod-template: "true"ラベルが付いている必要があります。 - Spec キー:
dataブロックに、PodSpecSchemaに準拠した JSON 文字列を値とするspecという名前のキーが含まれている必要があります(例:containers、volumes、restartPolicy)。 - 動作のカスタマイズ:
ConfigMapのメタデータにannotationsを設定して、高度なスポーナー連携(IAM ロールのバインド、初期化コンテナー、pre-stop ライフサイクルフックなど)を構成します。
テンプレート定義の例:
apiVersion: v1
kind: ConfigMap
metadata:
name: node-workspace-template
namespace: nogoo9
labels:
nogoo9/pod-template: "true"
annotations:
nogoo9/description: "A standard Node.js development sandbox with S3 storage sync"
nogoo9/tag: "node-20"
nogoo9/required-context: "PROJECT_NAME,REPO_URL"
nogoo9/iam-role-arn: "arn:aws:iam::123456789012:role/workspace-s3-access"
nogoo9/init-image: "alpine/git"
nogoo9/init-command: "git clone $REPO_URL /workspace/$PROJECT_NAME"
nogoo9/pre-stop-command: "aws s3 sync /workspace s3://my-workspace-backups/$PROJECT_NAME"
nogoo9/default-grace-period: "120"
data:
spec: |
{
"containers": [
{
"name": "workspace",
"image": "node:20-alpine",
"command": ["sleep", "infinity"],
"volumeMounts": [
{
"name": "workspace-storage",
"mountPath": "/workspace"
}
]
}
],
"volumes": [
{
"name": "workspace-storage",
"emptyDir": {}
}
]
}
2. サポートされているスポーナーのアノテーション
スポーナーは ConfigMap のメタデータアノテーション(および spawn_workspace の呼び出し時に渡されるカスタムのインラインアノテーション)を確認し、ワークスペースのライフサイクルをカスタマイズします。
| アノテーション/ラベルキー | 型 | 説明 |
|---|---|---|
nogoo9/workspace-auth-mode | アノテーション(カンマ区切り) | ワークスペースプロキシの認可モードを設定します。次の値をカンマ区切りで指定します。token-api(SPA 用に _auth/token と _auth/authorize でトークン取得エンドポイントを公開します)、inject-headers(ヘッダーを書き換えて、x-user-sub などのユーザー ID と JWT をコンテナに転送します。AUTH_ENABLED=true の場合、デフォルトで有効です)、no-auth(パブリックワークスペースのすべての認証/所有者チェックをバイパスします)。(v0.6.0 から利用可能。no-auth は v0.8.0 から利用可能) |
nogoo9/auth-require-token | アノテーション("true" または "false") | ワークスペースの動作に有効な未加工の OIDC アクセストークン/リフレッシュトークンが必須かどうかを指定します。true に設定すると、nocr_sess のみを使用したセッションクッキー認証は、ルーティングプロキシへのアクセス時に未認証として扱われます。そのため、新しい JWT トークンを認証して取得するため、ダッシュボードのログインページにリダイレクトされます。(v0.9.0 から利用可能) |
nogoo9/template-version | アノテーション(文字列) | Pod テンプレートのバージョンを指定します。ワークスペースが古いかどうかを追跡するために使用します。(v0.8.0 から利用可能) |
nogoo9/workspace-name | アノテーション(文字列) | ユーザーが定義したワークスペースの表示名を保存します。(v0.4.0 から利用可能) |
nogoo9/template-ref | アノテーション(文字列) | ワークスペースの起動に使用する Pod テンプレートへの参照です(例:default/workspace-terminal)。(v0.4.0 から利用可能) |
nogoo9/managed-by | ラベル(文字列) | この MCP サーバーが作成したワークスペース Pod にラベルを付け、操作対象の範囲を制限するために使用します。(v0.5.0 から利用可能) |
nogoo9/pod-template | ラベル("true") | Kubernetes の ConfigMap を再利用可能な Pod テンプレートとして識別します。 |
nogoo9/type | ラベル("workspace") | 実行中のエージェントワークスペース Pod を識別するため、スパナーによって自動的に付与されます。 |
nogoo9/workspace-id | ラベル | 実行中の Pod に関連付けられた一意のエージェントセッション/ワークスペース ID を識別します。 |
nogoo9/user-sub | ラベル/アノテーション | ワークスペース Pod の認証済みユーザーの subject(所有者)を表します。アクセス制御の検証と ServiceAccount のラベル付けに使用します。 |
nogoo9/description | アノテーション(文字列) | テンプレートの目的と内容を、人が読みやすい形で簡潔に説明します。 |
nogoo9/tag | アノテーション(文字列) | テンプレート環境に関連付けられたバージョンまたはタグです(例:node-20)。 |
nogoo9/required-context | アノテーション(カンマ区切り) | ツール呼び出しの context パラメーターで対象の環境変数が指定されていることを検証します(例:GITHUB_TOKEN,DATABASE_URL)。 |
nogoo9/iam-role-arn | アノテーション(AWS ロール ARN) | EKS IAM ロールマッピング(IRSA)用のアノテーションが付いた専用の Kubernetes ServiceAccount をプロビジョニングするよう、スパナーに指示します。 |
nogoo9/init-image | アノテーション(イメージ文字列) | 動的な spawner-init init コンテナで実行するコンテナイメージです。 |
nogoo9/init-command | アノテーション(シェルコマンド) | init コンテナで実行するシェルコマンドです。メインコンテナのボリュームマウントを自動的に共有します。 |
nogoo9/init-share-volumes | アノテーション("true" または "false") | 動的な init コンテナがメインコンテナのボリュームマウントを共有するかどうかを指定します。デフォルトは true です。(v0.5.5 から利用可能) |
nogoo9/pre-stop-command | アノテーション(シェルコマンド) | ワークスペースの終了時に Kubernetes の preStop ライフサイクル exec フックで実行するシェルコマンドです(例:状態の保存/プッシュ)。 |
nogoo9/pre-stop-sidecar-image | アノテーション(イメージ文字列) | pre-stop-command とともに指定すると、メインコンテナの代わりに専用のサイドカーコンテナ内で pre-stop コマンドを実行します。 |
nogoo9/default-grace-period | アノテーション(秒単位の数値) | Pod の terminationGracePeriodSeconds を上書きします(pre-stop コマンドが定義されている場合のデフォルトは 60 です)。クリーンアップコマンドが完了するための時間を確保します。 |
nogoo9/workspace-port | アノテーション(数値) | トラフィックをプロキシするコンテナ内のポートです。デフォルトは DEFAULT_WORKSPACE_PORT または 3000 です。 |
nogoo9/workspace-path | アノテーション(文字列) | ワークスペースのウェブインターフェースに対する、デフォルトの URL サブパスのマッピングです(デフォルトは / です)。 |
nogoo9/workspace-type | アノテーション(文字列) | メインエントリーポイントの形式指定です(例:iframe、novnc)。 |
nogoo9/preview-path | アノテーション(文字列) | UI のファイルプレビュータブに表示するデフォルトのフォルダーまたはファイルのサブパスです。 |
nogoo9/preview-type | アノテーション(文字列) | プレビュータブで使用する、代替のプレビュー表示モードです(例:markdown、html)。 |
nogoo9/api.<api-name>.port | アノテーション(数値) | ワークスペースが公開する追加の HTTP サービスポートを定義します。 |
nogoo9/api.<api-name>.visibility | アノテーション(文字列) | カスタム API エンドポイントのアクセス可視性を指定します。サポートされる値は、private(ワークスペース所有者のみアクセス可能)、internal(ログイン済みのすべてのユーザーがアクセス可能)、admin(所有者、または admin スコープとロールを持つユーザーがアクセス可能)、scope:<scope_name>(指定された OIDC スコープを持つユーザーがアクセス可能)、role:<role_name>(指定されたユーザーロールを持つユーザーがアクセス可能)、または許可するユーザー subject のカンマ区切りリストです。 |
nogoo9/api.<api-name>.path | アノテーション(文字列) | この API 固有のサブパスルーティングプレフィックスを定義します(例:/terminal)。 |
nogoo9/api.<api-name>.desc | アノテーション(文字列) | 追加 API の簡潔な説明です。UI に表示されます。 |
nogoo9/api.<api-name>.method | アノテーション(文字列) | サポートする HTTP メソッドのカンマ区切りリストです(例:GET,POST、*。デフォルトではすべてのメソッドが対象です)。 |
nogoo9/api.<api-name>.refresh | アノテーション(期間) | ダッシュボードカード内のカスタム統計/アクティビティ、その他のミニ API ビューの更新頻度を設定します(例:10s、1m、または起動時に一度だけクエリする場合は init)。 |
nogoo9/api.stats.refresh | アノテーション(期間) | ワークスペースのダッシュボードカードにある予約済みの stats API メトリクスの再読み込み頻度を明示的に設定します(例:10s、30s、init)。 |
nogoo9/api.last_activity.refresh | アノテーション(期間) | ワークスペースのダッシュボードカードにある予約済みの last_activity エポックタイムスタンプ API の再読み込み頻度を明示的に設定します(例:30s、1m、init)。 |
nogoo9/allowed-roles | アノテーション(カンマ区切り) | このテンプレートからのワークスペース起動を許可するユーザーロールのカンマ区切りリストです(例:developer,lead-dev)。管理者には常にロール制限が適用されません。 |
nogoo9/allowed-scopes | アノテーション(カンマ区切り) | このテンプレートからのワークスペース起動を許可する OAuth スコープのカンマ区切りリストです(例:nogoo9:write)。管理者には常にスコープ制限が適用されません。 |
📦 プログラム用 SDK と API プロキシサービス
@nogoo9/no-crd は、開発者がカスタムの Pod オーケストレーターを構築し、ワークスペースのトラフィックをネイティブにルーティングできるよう、プログラム用 SDK と動的なクラスター・ルーティング・プロキシを提供します。
1. コンポーザブルなプログラム用 SDK
Bun、Deno、または Node.js のコードベースに @nogoo9/no-crd をインポートすると、MCP HTTP サーバーを経由せずに、Pod サンドボックスとテンプレートをプログラムから制御できます。
import { KubeConfig } from "@kubernetes/client-node";
import {
initK8sContext,
spawnWorkspace,
stopWorkspace,
listWorkspaces
} from "@nogoo9/no-crd";
// 1. Initialize Kubernetes API Context (optionally pass custom configuration)
const kc = new KubeConfig();
kc.loadFromDefault();
const ctx = initK8sContext(kc);
// 2. Spawn a workspace sandbox from a template
const spawnResult = await spawnWorkspace(ctx, {
id: "agent-session-42",
templateRef: "nogoo9/default-agent-workspace",
context: {
"S3_BUCKET": "my-bucket",
"S3_FOLDER": "session-42"
}
});
console.log(`Spawned pod: ${spawnResult.podName}`);
// 3. List active workspaces running in the namespace
const list = await listWorkspaces(ctx, {
namespace: "nogoo9"
});
console.log(`Active workspaces count: ${list.workspaces.length}`);
// 4. Terminate the workspace sandbox
await stopWorkspace(ctx, {
id: "agent-session-42"
});
2. ワークスペース・ルーティング・プロキシ(試験的機能)
警告
ワークスペース・ルーティング・プロキシと JWT 認証エンジンは試験的な機能であり、次のバージョンで変更される可能性があります。
サーバーには、組み込みのリバースプロキシ・ルーティングサービスが含まれています。
次の宛先への HTTP リクエストは、
http://<mcp-server-host>/route/<workspace-id>/<subpath>
クラスター内で実行中のワークスペース Pod の IP アドレスに動的に直接プロキシされます。
AUTH_ENABLED が true の場合:
- トークンのブートストラップとパススコープ付き Cookie:標準的なブラウザーのナビゲーション(リンク、iframe)ではカスタム HTTP ヘッダーを送信できないため、クライアントは初回リダイレクト時に
?token=クエリパラメーターを使って有効な JWT を渡します。プロキシはこれを検証し、セキュアなパススコープ付き Cookie(nocr_token)を発行します。これにより、その後のリソースリクエスト(JS、CSS、画像、WebSocket)は URL パラメーターなしでシームレスに認証されます。 - 直接アクセス時のリダイレクト(SSO):有効な認証情報なしでワークスペース URL に直接アクセスすると、メインダッシュボードのログイン画面にリダイレクトされます。ログインすると、ダッシュボードは新しいブートストラップトークンを付けて、対象のワークスペース URL に自動的に戻します。
- リソース所有者の検証:ワークスペース Pod の
nogoo9/user-subラベルが JWT の subject claim と一致する必要があり、他のユーザーのワークスペースへの不正アクセスを防ぎます。 - プロキシの宛先ポート:ワークスペース Pod 内では、デフォルトで
3000が使用されます。Pod アノテーションnogoo9/workspace-portまたは環境変数DEFAULT_WORKSPACE_PORTで上書きできます。 - 複数ポート/カスタム API ルーティング:テンプレートでカスタムアノテーション(例:
nogoo9/api.terminal.port: "7681"、nogoo9/api.terminal.path: "/terminal")を定義すると、Pod 内の追加 API(ウェブターミナルやセカンダリサービスなど)を公開してルーティングできます。プロキシはサブパスのルーティングとメソッドのチェックを動的に処理します。 - 最初の JWT 検証が成功すると、ステートレスな署名付きセッション Cookie(
nocr_sess)が発行され、短期間のトークン有効期限が切れた後もワークスペースのトラフィックを維持できます。(v0.4.0 から利用可能) 設計の詳細については、ADR-002 と ADR-003 を参照してください。
リダイレクトのライフサイクル、Keycloak の設定、JWT クレームの詳細については、SSO と OIDC の統合ガイドを参照してください。
3. OAuth リソース検出(RFC 9728)
標準化されたメタデータエンドポイント GET /.well-known/oauth-protected-resource を公開し、次の情報を返します。
- 対応する認可サーバー。
- トークン形式の仕様。
- 必要なスコープ。
これにより、クライアントインターフェース(および MCP クライアント)がセキュリティ要件を自動的に検出し、動的な OAuth 認証フローを処理できます。
4. 埋め込み Web UI とダッシュボードテーマ
サーバーが HTTP/SSE トランスポートモードで実行されている場合、ビジュアル React Pod Manager UI Dashboard がルート / で直接配信されます(例:http://localhost:3000/)。
- ダッシュボードテーマ:UI にはシステム/ライト/ダークの切り替え機能があり、カスタムのビジュアルテーマもサポートしています。
- 3 つのソースを統合するテーママージエンジン:CSS スタイルシートは動的にスキャンされ、次のソースから統合されます。
- Kubernetes ConfigMap(
THEMES_CONFIGMAP環境変数)。 - カスタムローカルディレクトリ(
THEMES_DIR環境変数。デフォルトはthemes/)。 - 組み込みカタログ(Dracula、Nord、Stripe、Slack、Vercel、Apple、Superhuman、Notion、Antigravity のスタイルをあらかじめ収録)。
- Kubernetes ConfigMap(
テーマ ID が重複する場合、優先順位に従って解決されます:ConfigMap > ローカルディレクトリ > 組み込みカタログ。詳しいカスタマイズのガイドラインと CSS テンプレートについては、ダッシュボードテーマとブランディングガイドを参照してください。
🔌 API リファレンス(MCP ツールとリソース)
Pod ツール
list_pods:名前空間内の Pod の概要を取得します。labelSelector、fieldSelector、limitでフィルタリングできます。get_pod:対象 Pod 名の Kubernetes API JSON ペイロード全体を取得します。create_pod:コンテナ/ボリュームを直接指定して、カスタム Pod を作成します。patch_pod:Strategic Merge Patch を適用して、ラベル、アノテーション、コンテナのリソース制限を動的に変更します。delete_pod:オプションのgracePeriodSecondsを指定して Pod を終了します。get_pod_logs:tailLines、sinceSeconds、timestamps、limitBytes、previousなどのオプションを指定して、コンテナのログを取得します。list_namespaces:現在の認証情報でアクセス可能なすべての名前空間を一覧表示します。list_registry_images:設定済みのREGISTRY_URLからカタログイメージを一覧表示します。
Pod テンプレートツール
標準の Kubernetes ConfigMap(nogoo9/pod-template=true のラベル付き)として保存された、事前設定済みの Pod 仕様を管理します。
list_templates:利用可能なテンプレートを表示します。get_template:Pod テンプレート仕様の生データを取得します。create_template:新しい Pod テンプレート仕様を保存します。update_template:既存のテンプレートのラベル、アノテーション、または仕様を更新します。delete_template:テンプレートを削除します。create_pod_from_template:テンプレートを使って Pod を起動し、コンテナの上書き設定(環境変数、コマンド、リソース)と最上位の上書き設定を適用します。
エージェントワークスペース(Spawner)ツール
AI エージェントが自身のワークスペースサンドボックスを安全に起動し、クリーンアップできるように特別に設計されています。
list_workspaces:アクティブなエージェントワークスペースを一覧表示します(JWT/オーナーのマッピングに対応)。spawn_workspace:ワークスペース用のサンドボックス Pod を起動します。次の機能があります。- コンテキスト検証(
nogoo9/required-context):起動前に、呼び出し元が重要な環境変数(API キーなど)を指定する必要があります。 - 初期化コンテナ(
nogoo9/init-image/nogoo9/init-command):メインコンテナの起動前に、ワークスペースのディレクトリ/ファイルを初期化します。 - 停止前フック(
nogoo9/pre-stop-command):終了時にカスタムのクリーンアップコマンド(コードを git または S3 にコミット/同期するなど)を実行します。 - IAM ロールマッピング(
nogoo9/iam-role-arn):AWS EKS IAM ロールのサービスアカウントを動的にプロビジョニングします。
- コンテキスト検証(
stop_workspace:ワークスペース Pod をクリーンアップして終了します。
ユーティリティ
current_namespace:アクティブな名前空間とアクセスモードを返します。
MCP リソース
pod-template://{namespace}/{name}:保存された Pod テンプレートを読み取り専用の MCP リソースとして公開します。ui://nogoo9/app:埋め込み React/Web UI アプリを公開します(UI_ENABLED=trueかつビルド済みの場合)。サーバーが HTTP/SSE トランスポートモードで実行されている場合、UI は/または/uiでも直接配信されます(例:http://localhost:3000/)。また、postMessage に対応した MCP ホスト以外(標準的なブラウザータブや MCP Inspector など)で読み込まれた場合は、標準の HTTP JSON-RPC 呼び出しに自動的にフォールバックします。
🏗️ アーキテクチャ
┌───────────────────────┐
│ AI Agent / Client │
└───────────┬───────────┘
│ (Stdio or SSE Transport)
▼
┌───────────────────────┐
│ MCP Server │ <── (Queries ConfigMaps for specs)
└───────────┬───────────┘
│ (Kubernetes API - CoreV1)
▼
┌──────────────────────────────────────────┐
│ Kubernetes Cluster │
│ ┌────────────────────────────────────┐ │
│ │ Target Namespace │ │
│ │ ┌──────────┐ ┌──────────┐ ┌────┐ │ │
│ │ │ Agent │ │ Custom │ │ │ │ │
│ │ │ Sandbox │ │ Workload │ │... │ │ │
│ │ │ Pod │ │ Pod │ │ │ │ │
│ │ └──────────┘ └──────────┘ └────┘ │ │
│ └────────────────────────────────────┘ │
└──────────────────────────────────────────┘
サーバーは @kubernetes/client-node を使用して Kubernetes API と直接やり取りします。標準の Pod リソースと ConfigMap リソースを使用することで、セットアップは高いスケーラビリティを備え、クラスターオペレーターのインストールが不要で、厳格なエンタープライズの名前空間レベルのセキュリティポリシーにも容易に準拠できます。
🛠️ 開発
ツールチェーン管理とタスクの実行には Moon を、フォーマットとリンティングには Biome を使用しています。
前提条件
- Bun
1.3.11+ - Node.js
22.14.0+ - Moon
2.1.3+ - k3d(ローカル Kubernetes クラスター用)
環境のセットアップ
# Install dependencies
bun install
# Auto-fix code formatting and linting via Biome
bun run format
# Run TypeScript compilation checks
bun run typecheck
テストの実行
# Run unit tests
moon run mcp:test
# Run full spawner workspace lifecycle tests (requires local k3d)
bun run test:lifecycle
ローカルクラスターのテスト(k3d)
ローカルレジストリ、組み込みのモック S3、Traefik を備えたローカル k3d Kubernetes クラスターを起動します:
# Spin up development cluster
moon run k3d:bootstrap
# Rebuild, push, and deploy MCP server to the cluster
moon run mcp:deploy
# Tear down the cluster
moon run k3d:teardown
📄 ライセンス
このプロジェクトは Apache License 2.0 のもとでライセンスされています。詳細は LICENSE をご覧ください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。