Skip to content

Commit f374f35

Browse files
committed
feat(all): add language and runtime fields to MCP server metadata
Added language and runtime fields to MCP server configuration to enable better server identification and display in the debug endpoint. These fields flow from the database through backend API to satellite processes. Backend changes: - Added language and runtime fields to satellite config API response - Included fields in both active and error server configurations Satellite changes: - Updated TypeScript interfaces to include language and runtime fields - Fixed process spawn to pass language and runtime to running processes - Added fields to debug endpoint response for visibility - Updated command polling and config manager to handle new fields
1 parent a6aea6e commit f374f35

File tree

7 files changed

+49
-6
lines changed

7 files changed

+49
-6
lines changed

services/backend/src/routes/satellites/config.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ const CONFIG_RESPONSE_SCHEMA = {
4545
requires_oauth: { type: 'boolean', description: 'Whether this MCP server requires OAuth authentication' },
4646
user_id: { type: 'string', description: 'User ID for this specific instance (per-user process)' },
4747
user_slug: { type: 'string', description: 'User ID used in processId for this specific instance' },
48+
language: { type: 'string', description: 'Programming language (e.g., "typescript", "python", "go")' },
49+
runtime: { type: 'string', description: 'Runtime environment (e.g., "node", "python", "docker")' },
4850
secret_metadata: {
4951
type: 'object',
5052
properties: {
@@ -166,6 +168,9 @@ interface McpServerConfig {
166168
requires_oauth?: boolean;
167169
// Server source (for GitHub detection)
168170
source?: 'manual' | 'github' | 'official_registry' | null;
171+
// Language and runtime from mcpServers table
172+
language?: string;
173+
runtime?: string;
169174
settings?: {
170175
request_logging_enabled?: boolean;
171176
};
@@ -744,7 +749,10 @@ export default async function satelliteConfigRoute(server: FastifyInstance) {
744749
// OAuth support for HTTP/SSE MCP servers
745750
requires_oauth: server.requires_oauth || false,
746751
// Source (for GitHub detection)
747-
source: server.source as 'manual' | 'github' | 'official_registry' | null
752+
source: server.source as 'manual' | 'github' | 'official_registry' | null,
753+
// Language and runtime from mcpServers table
754+
language: server.language || undefined,
755+
runtime: server.runtime || undefined
748756
};
749757

750758
// DEBUG: Log source field being sent to satellite
@@ -1053,7 +1061,9 @@ export default async function satelliteConfigRoute(server: FastifyInstance) {
10531061
transport_type: server.transport_type as 'stdio' | 'http' | 'sse',
10541062
user_id: member.id,
10551063
user_slug: member.id,
1056-
enabled: false // Disabled due to processing error
1064+
enabled: false, // Disabled due to processing error
1065+
language: server.language || undefined,
1066+
runtime: server.runtime || undefined
10571067
};
10581068
}
10591069
} // Close member loop
@@ -1063,7 +1073,7 @@ export default async function satelliteConfigRoute(server: FastifyInstance) {
10631073
mcp_servers: mcpServerConfigs,
10641074
satellite_config: mergedConfig
10651075
};
1066-
1076+
10671077
request.log.info({
10681078
operation: 'satellite_config_retrieval',
10691079
satelliteId,

services/satellite/src/process/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ export interface MCPServerConfig {
1515
args: string[]; // ["-y", "@upstash/context7"]
1616
env: Record<string, string>; // Environment variables from three-tier config
1717
source?: 'manual' | 'github' | 'official_registry' | null; // Server source (for GitHub detection)
18+
language?: string; // Programming language (e.g., "typescript", "python", "go")
19+
runtime?: string; // Runtime environment (e.g., "node", "python", "docker")
1820
temp_dir?: string; // Temporary directory path (for GitHub deployments, cleanup on termination)
1921
}
2022

services/satellite/src/routes/status/debug.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ interface ServerInfo {
1818
status: string;
1919
command: string;
2020
args: string[];
21+
language?: string;
22+
runtime?: string;
2123
pid?: number;
2224
uptime_ms?: number;
2325
message_count?: number;
@@ -51,6 +53,8 @@ const serverInfoSchema = {
5153
status: { type: 'string' },
5254
command: { type: 'string' },
5355
args: { type: 'array', items: { type: 'string' } },
56+
language: { type: 'string' },
57+
runtime: { type: 'string' },
5458
pid: { type: 'number' },
5559
uptime_ms: { type: 'number' },
5660
message_count: { type: 'number' },
@@ -259,6 +263,8 @@ export async function registerDebugRoutes(server: FastifyInstance) {
259263
error_count: processInfo.errorCount,
260264
command: processInfo.config.command,
261265
args: processInfo.config.args,
266+
language: processInfo.config.language,
267+
runtime: processInfo.config.runtime,
262268
last_activity: new Date(processInfo.lastActivity).toISOString(),
263269
restart_count: status?.restart_count || 0,
264270
...backendStatusData
@@ -286,6 +292,8 @@ export async function registerDebugRoutes(server: FastifyInstance) {
286292
status: backendStatusData.backend_status || 'dormant',
287293
command: config.command,
288294
args: config.args,
295+
language: config.language,
296+
runtime: config.runtime,
289297
message: 'Process terminated due to inactivity, will respawn on next request',
290298
...backendStatusData
291299
});
@@ -319,6 +327,8 @@ export async function registerDebugRoutes(server: FastifyInstance) {
319327
status: backendStatusData.backend_status || 'configured',
320328
command: serverConfig.command || serverConfig.url || '',
321329
args: serverConfig.args || [],
330+
language: serverConfig.language,
331+
runtime: serverConfig.runtime,
322332
url: serverConfig.url,
323333
message: isOnline ? 'Server is online and ready' : (backendStatusData.backend_status ? `Server status: ${backendStatusData.backend_status}` : 'Server configured but not yet started'),
324334
...backendStatusData

services/satellite/src/server.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,9 @@ export async function createServer() {
401401
command: serverConfig.command!,
402402
args: serverConfig.args!,
403403
env: serverConfig.env || {},
404-
source: serverConfig.source // GitHub deployment detection
404+
source: serverConfig.source, // GitHub deployment detection
405+
language: serverConfig.language,
406+
runtime: serverConfig.runtime
405407
};
406408

407409
// Spawn the process with updated configuration
@@ -470,7 +472,9 @@ export async function createServer() {
470472
command: serverConfig.command!,
471473
args: serverConfig.args!,
472474
env: serverConfig.env || {},
473-
source: serverConfig.source // GitHub deployment detection
475+
source: serverConfig.source, // GitHub deployment detection
476+
language: serverConfig.language,
477+
runtime: serverConfig.runtime
474478
};
475479

476480
// Spawn the process

services/satellite/src/services/command-polling-service.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,12 @@ export interface McpServerConfig {
8888
/** Server source - for GitHub deployment detection */
8989
source?: 'manual' | 'github' | 'official_registry' | null;
9090

91+
/** Programming language (e.g., "typescript", "python", "go") */
92+
language?: string;
93+
94+
/** Runtime environment (e.g., "node", "python", "docker") */
95+
runtime?: string;
96+
9197
/** GitHub repository information (parsed from github: URLs) */
9298
github_owner?: string;
9399
github_repo?: string;

services/satellite/src/types/mcp-server.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,12 @@ export interface McpServerConfig {
6464
/** User ID that owns this instance (per-user process) */
6565
user_id?: string;
6666

67+
/** Programming language (e.g., "typescript", "python", "go") */
68+
language?: string;
69+
70+
/** Runtime environment (e.g., "node", "python", "docker") */
71+
runtime?: string;
72+
6773
/** Metadata about which fields contain secrets (for secure logging) */
6874
secret_metadata?: {
6975
/** Names of query parameters that are secrets */

services/satellite/src/utils/runtime-validator.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ import { spawnSync } from 'child_process';
88
* but required runtimes are missing on the system.
99
*/
1010

11+
interface Logger {
12+
info: (obj: Record<string, unknown>, msg: string) => void;
13+
fatal: (obj: Record<string, unknown>, msg: string) => void;
14+
}
15+
1116
interface RuntimeCheck {
1217
name: string; // Display name (e.g., "Node.js")
1318
commands: string[]; // Commands to check (e.g., ["node", "npx"])
@@ -207,7 +212,7 @@ function buildWarningMessage(result: RuntimeCheckResult): string {
207212
* @param logger - Logger instance (must have info() and fatal() methods)
208213
* @throws Never - Calls process.exit(1) on fatal errors
209214
*/
210-
export function validateSystemRuntimes(logger: { info: (msg: string) => void; fatal: (msg: string) => void }): void {
215+
export function validateSystemRuntimes(logger: Logger): void {
211216
// Check if skip flag is set
212217
const skipChecks = process.env.DEPLOYSTACK_SKIP_RUNTIME_CHECKS === 'true';
213218

0 commit comments

Comments
 (0)