Skip to content

Commit 46a897a

Browse files
committed
feat(all): enhance MCP config management and deploy wizard
- Add type selection (string/secret/boolean) to env vars and args in GitHub deploy wizard Step 4; env vars default to secret, args to string; secret fields use password input with eye toggle, boolean fields use true/false dropdown - Add PATCH /config-schema endpoint to add/remove env vars and args on GitHub-deployed MCP server installations without redeploying; guarded to source=github only; updates schema on mcpServers and encrypted values on mcpServerInstallations - Add "Add Configuration" button on config page with tabbed modal (env/args); remove buttons with confirmation on existing items - Fix masked secret values overwriting real secrets on save: frontend now sends only changed (pending) fields; backend merges partial updates with existing decrypted values before re-encrypting - Fix log retrieval order to oldest-first and append new logs on stream - Add max height to logs table - Add public repository selection and validation flow in deploy wizard - Emit deployment-failed event and track deployment status
1 parent c3bc5d2 commit 46a897a

29 files changed

+2621
-571
lines changed

services/backend/api-spec.json

Lines changed: 317 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12676,7 +12676,7 @@
1267612676
"tags": [
1267712677
"MCP Installations"
1267812678
],
12679-
"description": "Retrieves logs for a specific MCP installation with pagination and optional level filtering. Requires mcp.installations.logs.view permission. Logs are returned newest first.",
12679+
"description": "Retrieves logs for a specific MCP installation with pagination and optional level filtering. Requires mcp.installations.logs.view permission. Logs are returned oldest first.",
1268012680
"parameters": [
1268112681
{
1268212682
"schema": {
@@ -15494,18 +15494,60 @@
1549415494
"description": "Satellite ID to deploy on (optional, uses team default if omitted)"
1549515495
},
1549615496
"team_env": {
15497-
"type": "object",
15498-
"description": "Team-level environment variables",
15499-
"additionalProperties": {
15500-
"type": "string"
15497+
"type": "array",
15498+
"description": "Team-level environment variables with type information",
15499+
"items": {
15500+
"type": "object",
15501+
"properties": {
15502+
"name": {
15503+
"type": "string",
15504+
"minLength": 1
15505+
},
15506+
"value": {
15507+
"type": "string"
15508+
},
15509+
"type": {
15510+
"type": "string",
15511+
"enum": [
15512+
"string",
15513+
"secret",
15514+
"boolean"
15515+
]
15516+
}
15517+
},
15518+
"required": [
15519+
"name",
15520+
"value",
15521+
"type"
15522+
],
15523+
"additionalProperties": false
1550115524
}
1550215525
},
1550315526
"template_args": {
1550415527
"type": "array",
15528+
"description": "Additional command-line arguments for the MCP server with type information",
1550515529
"items": {
15506-
"type": "string"
15507-
},
15508-
"description": "Additional command-line arguments for the MCP server"
15530+
"type": "object",
15531+
"properties": {
15532+
"value": {
15533+
"type": "string",
15534+
"minLength": 1
15535+
},
15536+
"type": {
15537+
"type": "string",
15538+
"enum": [
15539+
"string",
15540+
"secret",
15541+
"boolean"
15542+
]
15543+
}
15544+
},
15545+
"required": [
15546+
"value",
15547+
"type"
15548+
],
15549+
"additionalProperties": false
15550+
}
1550915551
}
1551015552
},
1551115553
"required": [
@@ -30492,6 +30534,273 @@
3049230534
}
3049330535
}
3049430536
},
30537+
"/api/teams/{teamId}/mcp/installations/{installationId}/config-schema": {
30538+
"patch": {
30539+
"summary": "Add or remove config schema items for GitHub-deployed MCP servers",
30540+
"tags": [
30541+
"MCP Installations"
30542+
],
30543+
"description": "Allows team admins to add or remove team-level args and env vars on GitHub-deployed MCP server installations. Only works for servers with source=github.",
30544+
"requestBody": {
30545+
"required": true,
30546+
"content": {
30547+
"application/json": {
30548+
"schema": {
30549+
"type": "object",
30550+
"properties": {
30551+
"action": {
30552+
"type": "string",
30553+
"enum": [
30554+
"add",
30555+
"remove"
30556+
],
30557+
"description": "Whether to add or remove a config schema item"
30558+
},
30559+
"config_type": {
30560+
"type": "string",
30561+
"enum": [
30562+
"env",
30563+
"args"
30564+
],
30565+
"description": "Type of configuration to modify"
30566+
},
30567+
"item": {
30568+
"type": "object",
30569+
"properties": {
30570+
"name": {
30571+
"type": "string",
30572+
"minLength": 1,
30573+
"maxLength": 256
30574+
},
30575+
"type": {
30576+
"type": "string",
30577+
"enum": [
30578+
"string",
30579+
"secret",
30580+
"boolean"
30581+
]
30582+
},
30583+
"description": {
30584+
"type": "string",
30585+
"maxLength": 1024
30586+
},
30587+
"required": {
30588+
"type": "boolean"
30589+
},
30590+
"value": {
30591+
"type": "string",
30592+
"maxLength": 32768
30593+
}
30594+
},
30595+
"required": [
30596+
"name",
30597+
"type"
30598+
],
30599+
"description": "Schema item to add (required for add action)"
30600+
},
30601+
"item_name": {
30602+
"type": "string",
30603+
"minLength": 1,
30604+
"maxLength": 256,
30605+
"description": "Name of the item to remove (required for remove action)"
30606+
}
30607+
},
30608+
"required": [
30609+
"action",
30610+
"config_type"
30611+
],
30612+
"additionalProperties": false
30613+
}
30614+
}
30615+
}
30616+
},
30617+
"parameters": [
30618+
{
30619+
"schema": {
30620+
"type": "string",
30621+
"minLength": 1
30622+
},
30623+
"in": "path",
30624+
"name": "teamId",
30625+
"required": true,
30626+
"description": "Team ID that owns the installation"
30627+
},
30628+
{
30629+
"schema": {
30630+
"type": "string",
30631+
"minLength": 1
30632+
},
30633+
"in": "path",
30634+
"name": "installationId",
30635+
"required": true,
30636+
"description": "Installation ID"
30637+
}
30638+
],
30639+
"security": [
30640+
{
30641+
"cookieAuth": []
30642+
},
30643+
{
30644+
"bearerAuth": []
30645+
}
30646+
],
30647+
"responses": {
30648+
"200": {
30649+
"description": "Config schema updated successfully",
30650+
"content": {
30651+
"application/json": {
30652+
"schema": {
30653+
"type": "object",
30654+
"properties": {
30655+
"success": {
30656+
"type": "boolean"
30657+
},
30658+
"data": {
30659+
"type": "object",
30660+
"additionalProperties": true
30661+
},
30662+
"message": {
30663+
"type": "string"
30664+
}
30665+
},
30666+
"description": "Config schema updated successfully"
30667+
}
30668+
}
30669+
}
30670+
},
30671+
"400": {
30672+
"description": "Bad Request - Invalid input or validation error",
30673+
"content": {
30674+
"application/json": {
30675+
"schema": {
30676+
"type": "object",
30677+
"properties": {
30678+
"success": {
30679+
"type": "boolean",
30680+
"default": false,
30681+
"description": "Indicates the operation failed"
30682+
},
30683+
"error": {
30684+
"type": "string",
30685+
"description": "Error message describing what went wrong"
30686+
}
30687+
},
30688+
"required": [
30689+
"success",
30690+
"error"
30691+
],
30692+
"description": "Bad Request - Invalid input or validation error"
30693+
}
30694+
}
30695+
}
30696+
},
30697+
"401": {
30698+
"description": "Unauthorized - Authentication required or invalid token",
30699+
"content": {
30700+
"application/json": {
30701+
"schema": {
30702+
"type": "object",
30703+
"properties": {
30704+
"success": {
30705+
"type": "boolean",
30706+
"default": false,
30707+
"description": "Indicates the operation failed"
30708+
},
30709+
"error": {
30710+
"type": "string",
30711+
"description": "Error message describing what went wrong"
30712+
}
30713+
},
30714+
"required": [
30715+
"success",
30716+
"error"
30717+
],
30718+
"description": "Unauthorized - Authentication required or invalid token"
30719+
}
30720+
}
30721+
}
30722+
},
30723+
"403": {
30724+
"description": "Forbidden - Insufficient permissions or scope",
30725+
"content": {
30726+
"application/json": {
30727+
"schema": {
30728+
"type": "object",
30729+
"properties": {
30730+
"success": {
30731+
"type": "boolean",
30732+
"default": false,
30733+
"description": "Indicates the operation failed"
30734+
},
30735+
"error": {
30736+
"type": "string",
30737+
"description": "Error message describing what went wrong"
30738+
}
30739+
},
30740+
"required": [
30741+
"success",
30742+
"error"
30743+
],
30744+
"description": "Forbidden - Insufficient permissions or scope"
30745+
}
30746+
}
30747+
}
30748+
},
30749+
"404": {
30750+
"description": "Not Found - Resource not found",
30751+
"content": {
30752+
"application/json": {
30753+
"schema": {
30754+
"type": "object",
30755+
"properties": {
30756+
"success": {
30757+
"type": "boolean",
30758+
"default": false,
30759+
"description": "Indicates the operation failed"
30760+
},
30761+
"error": {
30762+
"type": "string",
30763+
"description": "Error message describing what went wrong"
30764+
}
30765+
},
30766+
"required": [
30767+
"success",
30768+
"error"
30769+
],
30770+
"description": "Not Found - Resource not found"
30771+
}
30772+
}
30773+
}
30774+
},
30775+
"500": {
30776+
"description": "Internal Server Error",
30777+
"content": {
30778+
"application/json": {
30779+
"schema": {
30780+
"type": "object",
30781+
"properties": {
30782+
"success": {
30783+
"type": "boolean",
30784+
"default": false,
30785+
"description": "Indicates the operation failed"
30786+
},
30787+
"error": {
30788+
"type": "string",
30789+
"description": "Error message describing what went wrong"
30790+
}
30791+
},
30792+
"required": [
30793+
"success",
30794+
"error"
30795+
],
30796+
"description": "Internal Server Error"
30797+
}
30798+
}
30799+
}
30800+
}
30801+
}
30802+
}
30803+
},
3049530804
"/api/teams/{teamId}/mcp/installations/{installationId}/user-configs": {
3049630805
"post": {
3049730806
"summary": "Create user configuration for MCP installation",

0 commit comments

Comments
 (0)