File tree Expand file tree Collapse file tree 5 files changed +385
-0
lines changed
Expand file tree Collapse file tree 5 files changed +385
-0
lines changed Original file line number Diff line number Diff line change @@ -125,3 +125,10 @@ NSJAIL_TMPFS_SIZE=100M
125125# Set to 0 to disable idle timeout (processes never sleep)
126126# Default: 180 seconds (3 minutes)
127127MCP_PROCESS_IDLE_TIMEOUT_SECONDS = 180
128+
129+ # Runtime Validation (optional)
130+ # Set to 'true' to skip system runtime checks at startup (Node.js, Python)
131+ # By default, satellite validates that required runtimes are installed before starting
132+ # Useful for CI/CD pipelines or Docker builds where runtimes are guaranteed
133+ # Default: false (validates Node.js and Python 3 availability)
134+ DEPLOYSTACK_SKIP_RUNTIME_CHECKS = false
Original file line number Diff line number Diff line change @@ -6,12 +6,24 @@ FROM node:24-bookworm-slim
66RUN useradd -m -d /opt/deploystack -s /bin/bash deploystack
77
88# Install essential runtime dependencies including gosu for privilege dropping
9+ # Python 3 and UV are required for Python-based MCP servers
910RUN apt-get update && \
1011 apt-get install -y --no-install-recommends \
1112 ca-certificates \
1213 gosu \
14+ python3 \
15+ python3-pip \
16+ python3-venv \
1317 && rm -rf /var/lib/apt/lists/*
1418
19+ # Install UV (Python package manager for MCP servers)
20+ # Using pip installation for reliable system-wide access
21+ # This installs both 'uv' and 'uvx' commands to /usr/local/bin
22+ RUN pip3 install --break-system-packages uv && \
23+ which uv && \
24+ which uvx && \
25+ uv --version
26+
1527# Create mcp-cache base directory with proper ownership
1628RUN mkdir -p /opt/deploystack/mcp-cache && \
1729 chown -R deploystack:deploystack /opt/deploystack
Original file line number Diff line number Diff line change @@ -51,6 +51,37 @@ npm start
5151
5252The satellite service uses environment variables for configuration and automatically manages persistent storage:
5353
54+ ## System Requirements
55+
56+ The satellite service requires the following runtimes to be installed on the system:
57+
58+ ### Required Runtimes
59+
60+ - ** Node.js 18+** - Requires both ` node ` (to build) and ` npm ` (to execute/install packages) for spawning MCP servers
61+ - ** Python 3.8+** - Requires ` python3 ` (to build) for Python-based MCP servers
62+ - ** UV Package Manager** - Requires ` uvx ` (to start/execute) for Python async MCP servers
63+
64+ ### Optional Runtimes
65+
66+ - ** python** - Legacy Python symlink (warns if missing, not required)
67+
68+ ### Runtime Validation
69+
70+ The satellite automatically validates that required runtimes are installed during startup:
71+
72+ - ** PATH-based detection** : Checks if commands are available in your system PATH (same as shell command lookup)
73+ - ** Works everywhere** : Finds commands regardless of installation location (Homebrew, custom paths, etc.)
74+ - ** Fail-fast** : If required runtimes are missing, satellite exits with a clear error message
75+ - ** All commands required** : For Node.js, both ` node ` AND ` npm ` must be present. For Python, both ` python3 ` AND ` uvx ` must be present.
76+
77+ To skip runtime validation (e.g., for CI/CD or Docker builds):
78+
79+ ``` bash
80+ DEPLOYSTACK_SKIP_RUNTIME_CHECKS=true npm start
81+ ```
82+
83+ ** Note** : Skipping runtime checks is not recommended. MCP servers will fail at spawn time if runtimes are actually missing.
84+
5485### Persistent Storage
5586
5687Satellites maintain registration state across restarts using local file storage:
Original file line number Diff line number Diff line change @@ -23,6 +23,7 @@ import { McpActivityTracker } from './services/mcp-activity-tracker';
2323import { ToolSearchService } from './services/tool-search-service' ;
2424import { OAuthTokenService } from './services/oauth-token-service' ;
2525import { SsePingService } from './services/sse-ping-service' ;
26+ import { validateSystemRuntimes } from './utils/runtime-validator.js' ;
2627
2728/**
2829 * Validate registration token format and availability
@@ -154,6 +155,17 @@ export async function createServer() {
154155 validateSatelliteName ( satelliteName , tempLogger ) ;
155156 validateRegistrationToken ( registrationToken , tempLogger ) ;
156157
158+ // STEP 1.5: Validate system runtimes (Node.js, Python)
159+ tempLogger . info ( { operation : 'runtime_validation_start' } , 'Validating system runtimes...' ) ;
160+ const skipRuntimeChecks = process . env . DEPLOYSTACK_SKIP_RUNTIME_CHECKS === 'true' ;
161+
162+ if ( skipRuntimeChecks ) {
163+ tempLogger . info ( { operation : 'runtime_validation_skipped' } , 'Runtime validation skipped (DEPLOYSTACK_SKIP_RUNTIME_CHECKS=true)' ) ;
164+ } else {
165+ validateSystemRuntimes ( tempLogger ) ;
166+ tempLogger . info ( { operation : 'runtime_validation_complete' } , 'System runtime validation passed' ) ;
167+ }
168+
157169 const server = fastify ( {
158170 logger : loggerConfig ,
159171 disableRequestLogging : true ,
You can’t perform that action at this time.
0 commit comments