@nogoo9/no-crd
Agent-Driven, On-Demand Pod Orchestration in Kubernetes — Without Custom Resource Definitions.
Agenten stärken
Der eigene Befehl des Herausgebers. Kein PlugMCP-Endpunkt.
Host a copy with our keys and logs.
npx -y @nogoo9/[email protected]Claude Code hat keinen Installationslink für einen lokalen Befehl. Kopieren Sie den Befehl unten und führen Sie ihn in einem Terminal aus.
KUBECONFIG=<value> BASE_URL=<value> STATELESS=<value> TLS_CERT=<value> TLS_KEY=<secret> TLS_CA=<value> NODE_TLS_REJECT_UNAUTHORIZED=<value> REGISTRY_URL=<value> TEMPLATES_DIR=<value> BUILTIN_TEMPLATES=<value> AUTH_ENABLED=<value> JWT_VERIFICATION_REQUIRED=<value> JWT_SECRET=<secret> JWT_PUBLIC_KEY=<secret> JWKS_URI=<value> INTROSPECTION_ENDPOINT=<value> OAUTH_CLIENT_ID=<value> OAUTH_CLIENT_SECRET=<secret> JWT_AUDIENCE=<value> AUTH_ISSUER=<value> AUTH_SUB_JSONPATH=<value> AUTH_ADMIN_ROLE=<value> AUTH_ADMIN_USERS=<value> PROXY_SESSION_TTL=<value> PROXY_SESSION_SECRET=<secret> UI_ENABLED=<value> THEMES_DIR=<value> THEMES_CONFIGMAP=<value> DOCS_DIR=<value> OAUTH_DISCOVERY_URL=<value> OAUTH_LOGIN_METHOD=<value> UI_TITLE=<value> UI_SUBTITLE=<value> claude mcp add io.github.nogoo9-no-crd -- npx -y @nogoo9/no-crd@0.18.0In einem Terminal ausführen.
{ "mcpServers": { "io.github.nogoo9-no-crd": { "command": "npx", "args": [ "-y", "@nogoo9/[email protected]" ], "env": { "KUBECONFIG": "<value>", "BASE_URL": "<value>", "STATELESS": "<value>", "TLS_CERT": "<value>", "TLS_KEY": "<secret>", "TLS_CA": "<value>", "NODE_TLS_REJECT_UNAUTHORIZED": "<value>", "REGISTRY_URL": "<value>", "TEMPLATES_DIR": "<value>", "BUILTIN_TEMPLATES": "<value>", "AUTH_ENABLED": "<value>", "JWT_VERIFICATION_REQUIRED": "<value>", "JWT_SECRET": "<secret>", "JWT_PUBLIC_KEY": "<secret>", "JWKS_URI": "<value>", "INTROSPECTION_ENDPOINT": "<value>", "OAUTH_CLIENT_ID": "<value>", "OAUTH_CLIENT_SECRET": "<secret>", "JWT_AUDIENCE": "<value>", "AUTH_ISSUER": "<value>", "AUTH_SUB_JSONPATH": "<value>", "AUTH_ADMIN_ROLE": "<value>", "AUTH_ADMIN_USERS": "<value>", "PROXY_SESSION_TTL": "<value>", "PROXY_SESSION_SECRET": "<secret>", "UI_ENABLED": "<value>", "THEMES_DIR": "<value>", "THEMES_CONFIGMAP": "<value>", "DOCS_DIR": "<value>", "OAUTH_DISCOVERY_URL": "<value>", "OAUTH_LOGIN_METHOD": "<value>", "UI_TITLE": "<value>", "UI_SUBTITLE": "<value>" } } }}claude_desktop_config.json
Remote-URL oder ein Befehl auf Ihrem Rechner? Worin sich die beiden Installationen unterscheiden
Auf PlugMCP ausführen
A new server you create. It is not this listing's official endpoint. Use the publisher install when you want their URL and their credentials.
Starten@nogoo9/no-crd is a lightweight, cross-runtime Model Context Protocol (MCP) server that empowers AI agents and APIs to dynamically spawn, route to, and manage ephemeral containerized sandboxes on standard Kubernetes (k8s/k3s) clusters — without requiring Custom Resource Definitions (CRDs), cluster-level operators, or elevated RBAC permissions.
It provides JupyterHub-like dynamic pod lifecycle management but is completely agnostic to actual workloads and supports multi-runtime execution under Bun, Deno, and Node.js.
📚 For detailed guides, API reference, and configuration options, visit the public Documentation Website or access the built-in documentation served directly at /docs/ (e.g. http://localhost:3000/docs/) when running the server.
To get started with @nogoo9/no-crd, select the track that matches your goals:
no-crd to Cursor, Claude Desktop, Cline, or Roo Code to let your agent manage pods.nocr_token and nocr_sess), and automatic HMAC-signed session management for short-lived token resilience.# 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 run -d -p 3000:3000 \
-v "$HOME/.kube/config:/app/.kube/config:ro" \
-e KUBECONFIG=/app/.kube/config \
ghcr.io/nogoo9/no-crd:latest
The server and command-line utility are configurable using CLI options or environment variables. Below is the quick reference table of all settings:
For the @nogoo9/no-crd MCP server to interact with Kubernetes, it must run with appropriate RBAC permissions. Depending on your configuration, you can deploy it with Cluster-Wide (ClusterRole) access or Namespace-Scoped (Role) access.
Below is the mapping showing which Kubernetes API resources and verbs each MCP tool requires. The server dynamically checks these permissions at startup (via SelfSubjectAccessReview) and only registers tools that the active identity is authorized to use.
configmapseventsnamespacespodspods/logMODE=cluster)Use this mode if you want the MCP server to manage sandboxes across any namespace in the cluster.
Create a ClusterRole and 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
MODE=namespaced)Use this mode if the MCP server should be restricted to a single namespace (e.g. nogoo9). In this mode, no cluster-level or administrative permissions are needed.
Create a Role and RoleBinding in the target namespace:
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
(Note: In namespace-scoped mode, the list_namespaces tool will only return the target namespace, and namespace parameter inputs to all tools will default to the target namespace.)
Templates in @nogoo9/no-crd can be loaded from three sources (highest to lowest priority):
nogoo9/pod-template: "true" (original mechanism)TEMPLATES_DIR env var (YAML or JSON files)BUILTIN_TEMPLATES=false)See ADR-001 for format details.
To register a template with the spawner, create a ConfigMap meeting the following requirements:
nogoo9/pod-template: "true".data block must contain a key named spec whose value is a JSON string conforming to the PodSpecSchema (e.g. containers, volumes, restartPolicy).annotations on the ConfigMap metadata to configure advanced spawner integrations (like IAM role binding, init containers, and pre-stop lifecycle hooks).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": {}
}
]
}
The spawner inspects ConfigMap metadata annotations (and custom inline annotations passed during spawn_workspace) to customize the workspace lifecycle:
@nogoo9/no-crd provides a complete programmatic SDK and dynamic cluster routing proxy to allow developers to build custom pod orchestrators and route workspace traffic natively.
You can import @nogoo9/no-crd in your Bun, Deno, or Node.js codebase to control pod sandboxes and templates programmatically, bypassing the MCP HTTP server.
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"
});
[!WARNING] The workspace routing proxy and JWT authentication engine are experimental and likely to change in the next version.
The server includes a built-in reverse proxy routing service. HTTP requests targeting:
http://<mcp-server-host>/route/<workspace-id>/<subpath>
are dynamically proxied directly to the running workspace pod's IP address inside the cluster.
If AUTH_ENABLED is true:
?token= query parameter on initial redirect. The proxy validates it and issues a secure, path-scoped cookie (nocr_token), allowing subsequent resource requests (JS, CSS, images, WebSockets) to authenticate seamlessly without URL parameters.nogoo9/user-sub label must match the JWT's subject claim, preventing unauthorized access to other users' workspaces.3000 or can be overridden via pod annotation nogoo9/workspace-port or the DEFAULT_WORKSPACE_PORT environment variable.nogoo9/api.terminal.port: "7681", nogoo9/api.terminal.path: "/terminal"). The proxy will dynamically handle subpath routing and method checks.nocr_sess) is minted on first successful JWT validation, enabling workspace traffic to survive short-lived token expiry. (Available from v0.4.0) See ADR-002 and ADR-003 for design details.For a detailed breakdown of the redirection lifecycle, Keycloak configuration, and JWT claims, see the SSO & OIDC Integration Guide.
Exposes the standardized metadata endpoint GET /.well-known/oauth-protected-resource returning:
This allows client interfaces (and MCP clients) to automatically discover security requirements and handle dynamic OAuth authentication flows.
When the server runs in HTTP/SSE transport mode, the visual React Pod Manager UI Dashboard is served directly at root / (e.g. http://localhost:3000/).
THEMES_CONFIGMAP environment variable).THEMES_DIR environment variable, defaults to themes/).Duplicate theme IDs are resolved according to priority: ConfigMap > Local Directory > Built-In Catalog. For detailed customization guidelines and CSS templates, see the Dashboard Themes & Branding Guide.
list_pods: Retrieve a summary of pods in the namespace. Filters by labelSelector, fieldSelector, and limit.get_pod: Fetch full Kubernetes API JSON payload for a target pod name.create_pod: Create a custom pod with direct container/volume specifications.patch_pod: Apply a Strategic Merge Patch to modify labels, annotations, or container resource limits dynamically.delete_pod: Terminate a pod with optional gracePeriodSeconds.get_pod_logs: Fetch logs for a container with options like tailLines, sinceSeconds, timestamps, limitBytes, and previous.list_namespaces: List all namespaces accessible with current credentials.list_registry_images: List catalog images from the configured REGISTRY_URL.Manage preconfigured pod specifications stored as standard Kubernetes ConfigMaps (labeled nogoo9/pod-template=true).
list_templates: Show available templates.get_template: Get the raw pod template spec.create_template: Store a new pod template spec.update_template: Update labels, annotations, or specs on an existing template.delete_template: Delete a template.create_pod_from_template: Spawn a pod using a template, applying container overrides (environment variables, commands, resources) and top-level overrides.Specially designed for AI agents to safely spawn and clean up their own workspace sandboxes.
list_workspaces: List active agent workspaces (with JWT/owner mapping support).spawn_workspace: Spawn a workspace sandbox pod. Features:
nogoo9/required-context): Requires the caller to supply critical env variables (e.g. API keys) before spawning.nogoo9/init-image / nogoo9/init-command): Initialize workspace directories/files before main containers start.nogoo9/pre-stop-command): Run custom cleanup commands (e.g., commit/sync code to git or S3) upon termination.nogoo9/iam-role-arn): Dynamically provisions AWS EKS IAM Role service accounts.stop_workspace: Clean up and terminate the workspace pod.current_namespace: Returns active namespace and access mode.pod-template://{namespace}/{name}: Exposes stored pod templates directly as read-only MCP resources.ui://nogoo9/app: Exposes the embedded React/web UI app (if UI_ENABLED=true and built). When the server runs in HTTP/SSE transport mode, the UI is also served directly at / or /ui (e.g. http://localhost:3000/) and automatically falls back to standard HTTP JSON-RPC calls when loaded outside a postMessage-compatible MCP host (such as in a standard browser tab or the MCP Inspector). ┌───────────────────────┐
│ 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 │ │ │ │ │
│ │ └──────────┘ └──────────┘ └────┘ │ │
│ └────────────────────────────────────┘ │
└──────────────────────────────────────────┘
The server interacts directly with the Kubernetes API using @kubernetes/client-node. By using standard Pod and ConfigMap resources, the setup is highly scalable, requires no cluster operator installs, and easily adheres to strict enterprise namespace-level security policies.
1.3.11+22.14.0+2.1.3+# 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
Bootstrap a local k3d Kubernetes cluster complete with a local registry, built-in mock S3, and Traefik:
# 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
This project is licensed under the Apache License 2.0. See LICENSE for details.
Dynamic pod spawner & proxy for ephemeral AI agent workspaces on Kubernetes without CRDs
{ "mcpServers": { "io.github.nogoo9-no-crd": { "command": "npx", "args": [ "-y", "@nogoo9/[email protected]" ], "env": { "KUBECONFIG": "<value>", "BASE_URL": "<value>", "STATELESS": "<value>", "TLS_CERT": "<value>", "TLS_KEY": "<secret>", "TLS_CA": "<value>", "NODE_TLS_REJECT_UNAUTHORIZED": "<value>", "REGISTRY_URL": "<value>", "TEMPLATES_DIR": "<value>", "BUILTIN_TEMPLATES": "<value>", "AUTH_ENABLED": "<value>", "JWT_VERIFICATION_REQUIRED": "<value>", "JWT_SECRET": "<secret>", "JWT_PUBLIC_KEY": "<secret>", "JWKS_URI": "<value>", "INTROSPECTION_ENDPOINT": "<value>", "OAUTH_CLIENT_ID": "<value>", "OAUTH_CLIENT_SECRET": "<secret>", "JWT_AUDIENCE": "<value>", "AUTH_ISSUER": "<value>", "AUTH_SUB_JSONPATH": "<value>", "AUTH_ADMIN_ROLE": "<value>", "AUTH_ADMIN_USERS": "<value>", "PROXY_SESSION_TTL": "<value>", "PROXY_SESSION_SECRET": "<secret>", "UI_ENABLED": "<value>", "THEMES_DIR": "<value>", "THEMES_CONFIGMAP": "<value>", "DOCS_DIR": "<value>", "OAUTH_DISCOVERY_URL": "<value>", "OAUTH_LOGIN_METHOD": "<value>", "UI_TITLE": "<value>", "UI_SUBTITLE": "<value>" } } }}Tools
Noch keine Tool-Liste. Remote-Server erhalten eine nach dem ersten Health-Check.
FAQ
Kopieren Sie auf dieser Seite die stdio-Konfiguration für Cursor, Claude Desktop, Claude Code oder VS Code. Sie nutzt die Installation des Herausgebers, keinen PlugMCP-Proxy.
Der Herausgeber nennt diese Umgebungsvariablen: KUBECONFIG, BASE_URL, STATELESS, TLS_CERT, TLS_KEY, TLS_CA, NODE_TLS_REJECT_UNAUTHORIZED, REGISTRY_URL, TEMPLATES_DIR, BUILTIN_TEMPLATES, AUTH_ENABLED, JWT_VERIFICATION_REQUIRED, JWT_SECRET, JWT_PUBLIC_KEY, JWKS_URI, INTROSPECTION_ENDPOINT, OAUTH_CLIENT_ID, OAUTH_CLIENT_SECRET, JWT_AUDIENCE, AUTH_ISSUER, AUTH_SUB_JSONPATH, AUTH_ADMIN_ROLE, AUTH_ADMIN_USERS, PROXY_SESSION_TTL, PROXY_SESSION_SECRET, UI_ENABLED, THEMES_DIR, THEMES_CONFIGMAP, DOCS_DIR, OAUTH_DISCOVERY_URL, OAUTH_LOGIN_METHOD, UI_TITLE, UI_SUBTITLE.
No Crd läuft lokal über stdio.
Zuletzt geprüft: 2026-11-10. Dynamic pod spawner & proxy for ephemeral AI agent workspaces on Kubernetes without CRDs