Skip to content

Commit a56dcf6

Browse files
Dumbrisclaude
andcommitted
Merge origin/main (post-#805); regenerate OpenAPI from merged code
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2 parents 77aa802 + ed42d46 commit a56dcf6

25 files changed

Lines changed: 1324 additions & 47 deletions

cmd/mcpproxy-tray/internal/api/adapter.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"os"
77
"path/filepath"
88
"runtime"
9+
"strings"
910

1011
internalRuntime "github.com/smart-mcp-proxy/mcpproxy-go/internal/runtime"
1112
"github.com/smart-mcp-proxy/mcpproxy-go/internal/tray"
@@ -307,8 +308,15 @@ func (a *ServerAdapter) ReloadConfiguration() error {
307308
return fmt.Errorf("ReloadConfiguration not yet supported via API")
308309
}
309310

310-
// GetConfigPath returns the configuration file path
311+
// GetConfigPath returns the configuration file path core is running with.
312+
// The tray passes MCPPROXY_TRAY_CONFIG_PATH to core as --config (see
313+
// buildCoreArgs in main.go), so tray-side config consumers — e.g. the Spec 079
314+
// update_check gate — must resolve to that same override, not a hardcoded
315+
// default. Falls back to the default ~/.mcpproxy path when unset.
311316
func (a *ServerAdapter) GetConfigPath() string {
317+
if cfg := strings.TrimSpace(os.Getenv("MCPPROXY_TRAY_CONFIG_PATH")); cfg != "" {
318+
return cfg
319+
}
312320
homeDir, err := os.UserHomeDir()
313321
if err != nil {
314322
return "~/.mcpproxy/mcp_config.json" // fallback

cmd/mcpproxy-tray/internal/api/adapter_test.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,3 +645,30 @@ func TestHealthDataFlow_EndToEnd(t *testing.T) {
645645
status := adapter.GetStatus().(map[string]interface{})
646646
assert.Equal(t, 1, status["connected_servers"], "Status should use health.level for connected count")
647647
}
648+
649+
// =============================================================================
650+
// ServerAdapter.GetConfigPath Tests
651+
// =============================================================================
652+
653+
// The tray launches core with --config <MCPPROXY_TRAY_CONFIG_PATH> (see
654+
// buildCoreArgs in main.go). GetConfigPath must resolve to that SAME path so
655+
// tray-side config consumers (e.g. the Spec 079 update_check gate) read the
656+
// config core is actually using — not a hardcoded default.
657+
func TestServerAdapter_GetConfigPath_HonorsTrayConfigPathEnv(t *testing.T) {
658+
const custom = "/tmp/custom-tray-config/mcp_config.json"
659+
t.Setenv("MCPPROXY_TRAY_CONFIG_PATH", custom)
660+
661+
adapter := NewServerAdapter(NewMockClient())
662+
663+
assert.Equal(t, custom, adapter.GetConfigPath())
664+
}
665+
666+
func TestServerAdapter_GetConfigPath_DefaultWhenEnvUnset(t *testing.T) {
667+
t.Setenv("MCPPROXY_TRAY_CONFIG_PATH", "")
668+
669+
adapter := NewServerAdapter(NewMockClient())
670+
671+
got := adapter.GetConfigPath()
672+
assert.Contains(t, got, "mcp_config.json")
673+
assert.NotEqual(t, "", got)
674+
}

docs/api/rest-api.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -852,7 +852,7 @@ Get application info, version, and update availability.
852852
| `listen_addr` | string | Server listen address |
853853
| `endpoints.http` | string | HTTP API endpoint address |
854854
| `endpoints.socket` | string | Unix socket path (empty if disabled) |
855-
| `update` | object | Update information (may be null if not checked yet) |
855+
| `update` | object | Update information (may be null if not checked yet; omitted entirely when update checking is disabled via `update_check.enabled: false` or `MCPPROXY_DISABLE_AUTO_UPDATE=true`) |
856856
| `update.available` | boolean | Whether a newer version is available |
857857
| `update.latest_version` | string | Latest version available on GitHub |
858858
| `update.release_url` | string | URL to the GitHub release page |
@@ -861,7 +861,7 @@ Get application info, version, and update availability.
861861
| `update.check_error` | string | Error message if update check failed |
862862

863863
:::tip Update Checking
864-
MCPProxy automatically checks for updates every 4 hours. The update information is exposed via this endpoint and used by the tray application and web UI to show update notifications.
864+
MCPProxy automatically checks for updates every 4 hours. The update information is exposed via this endpoint and used by the tray application and web UI to show update notifications. Use `?refresh=true` to force an immediate re-check. Checking is controlled by the `update_check` config block (`enabled`, `channel`) — see [Version Updates](/features/version-updates); when disabled, `?refresh=true` performs no check and the `update` object is omitted.
865865
:::
866866

867867
### Docker

docs/cli/status-command.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ When the daemon is running, `status` surfaces the result of the background updat
151151
- **Update available**: `Version: v1.2.0 (update available: v1.3.0 — <release URL>)`
152152
- **Up to date**: `Version: v1.3.0 (latest)`
153153
- **Check failed or not yet completed** (offline, rate-limited): the version is shown without any annotation. In JSON output the `update.check_error` field retains the failure reason for diagnostics.
154+
- **Update checking disabled** (`update_check.enabled: false` in the config, or `MCPPROXY_DISABLE_AUTO_UPDATE=true`): the daemon performs no check and omits the `update` object entirely, so the version is shown without any annotation.
154155

155156
In machine-readable output (`-o json`/`-o yaml`) the `update` object also carries `checked_at` (when the last successful check ran, so consumers can judge staleness) and `is_prerelease` (whether the offered version is a prerelease), matching the `/api/v1/info` contract.
156157

docs/configuration.md

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ Complete reference for MCPProxy configuration file (`mcp_config.json`). This doc
1717
11. [Code Execution](#code-execution)
1818
12. [Feature Flags](#feature-flags)
1919
13. [Registries](#registries)
20-
14. [Complete Example](#complete-example)
20+
14. [Update Check](#update-check)
21+
15. [Complete Example](#complete-example)
2122

2223
---
2324

@@ -1033,6 +1034,49 @@ and are hot-reloadable. Non-positive values fall back to the defaults.
10331034

10341035
---
10351036

1037+
## Update Check
1038+
1039+
Controls the background upgrade-awareness checker (Spec 079). MCPProxy
1040+
periodically queries GitHub Releases and surfaces "update available" on
1041+
`mcpproxy status` / `doctor`, a startup log line, the Web UI (sidebar badge +
1042+
dismissible banner), and the trays. Checks never block and fail silently when
1043+
offline.
1044+
1045+
```json
1046+
{
1047+
"update_check": {
1048+
"enabled": true,
1049+
"channel": "stable"
1050+
}
1051+
}
1052+
```
1053+
1054+
| Field | Type | Default | Description |
1055+
|-------|------|---------|-------------|
1056+
| `enabled` | boolean | `true` | Master switch for update checking. When `false`, no network check is performed (background poll *and* the manual `/api/v1/info?refresh=true` re-check) and no upgrade nudge appears on any surface — the `update` object is omitted from `/api/v1/info`. |
1057+
| `channel` | string | `"stable"` | Release channel: `"stable"` (GitHub `releases/latest`; prereleases never offered) or `"rc"` (prerelease tags such as `v0.47.0-rc.1` included). |
1058+
1059+
Both keys are optional and hot-reloadable: editing them (config file or
1060+
`POST /api/v1/config/apply`) takes effect without a restart, and re-enabling
1061+
triggers a prompt re-check.
1062+
1063+
**Environment-variable precedence** — the existing switches keep working and
1064+
**win over** the config keys (operator override):
1065+
1066+
| Variable | Effect |
1067+
|----------|--------|
1068+
| `MCPPROXY_DISABLE_AUTO_UPDATE=true` | Force-disables update checking even when `update_check.enabled` is `true`. |
1069+
| `MCPPROXY_ALLOW_PRERELEASE_UPDATES=true` | Force-selects the prerelease (`rc`) channel even when `update_check.channel` is `stable`. |
1070+
1071+
The env vars only widen in one direction (disable checks / enable
1072+
prereleases); they cannot force-enable checking that config disabled — with
1073+
`update_check.enabled: false`, checks stay off regardless of environment.
1074+
1075+
See [Version Updates](features/version-updates.md) for where updates are
1076+
surfaced.
1077+
1078+
---
1079+
10361080
## Complete Example
10371081

10381082
Here's a complete configuration example with all major sections:

docs/configuration/config-file.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ MCPProxy uses a JSON configuration file located at `~/.mcpproxy/mcp_config.json`
3838
"features": {
3939
"enable_web_ui": true
4040
},
41+
"update_check": {
42+
"enabled": true,
43+
"channel": "stable"
44+
},
4145
"mcpServers": []
4246
}
4347
```
@@ -112,6 +116,23 @@ Both cadences are configurable globally, and can be overridden per server (see [
112116
| `code_execution_max_tool_calls` | integer | `0` | Maximum tool calls (0 = unlimited) |
113117
| `code_execution_pool_size` | integer | `10` | VM pool size for code execution |
114118

119+
### Update Check Settings
120+
121+
Controls the background upgrade-awareness checker. Both keys are optional and
122+
hot-reloadable (no restart needed).
123+
124+
| Option | Type | Default | Description |
125+
|--------|------|---------|-------------|
126+
| `update_check.enabled` | boolean | `true` | Master switch. When `false`, no network check runs (background poll and manual re-check) and no upgrade nudge appears on any surface — the `update` object is omitted from `/api/v1/info`. |
127+
| `update_check.channel` | string | `"stable"` | Release channel: `"stable"` (prereleases never offered) or `"rc"` (prerelease tags like `v0.47.0-rc.1` included). |
128+
129+
The existing environment switches keep working and **win over** these keys:
130+
`MCPPROXY_DISABLE_AUTO_UPDATE=true` force-disables checking, and
131+
`MCPPROXY_ALLOW_PRERELEASE_UPDATES=true` force-selects the prerelease channel.
132+
They only widen in one direction — they cannot re-enable checking that the
133+
config disabled. See [Version Updates](/features/version-updates) for where
134+
updates are surfaced.
135+
115136
### MCP Servers
116137

117138
See [Upstream Servers](/configuration/upstream-servers) for detailed server configuration.

docs/configuration/environment-variables.md

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -111,14 +111,19 @@ The tray application doesn't read the config file directly. It launches the core
111111
| `MCPPROXY_TRAY_ENDPOINT` | Override tray-core communication endpoint (unix:///path/socket.sock or npipe:////./pipe/name) | Auto-detect |
112112
| `MCPPROXY_TRAY_INSPECT_ADDR` | Address for tray instrumentation/debug server | - |
113113

114-
### Auto-Update Settings (Tray)
114+
### Auto-Update Settings
115115

116116
| Variable | Description | Default |
117117
|----------|-------------|---------|
118-
| `MCPPROXY_DISABLE_AUTO_UPDATE` | Disable automatic update checks | `false` |
119-
| `MCPPROXY_UPDATE_NOTIFY_ONLY` | Only notify about updates, don't auto-install | `false` |
120-
| `MCPPROXY_ALLOW_PRERELEASE_UPDATES` | Allow prerelease/beta version updates | `false` |
121-
| `MCPPROXY_UPDATE_APP_BUNDLE` | Enable app bundle updates (macOS) | `false` |
118+
| `MCPPROXY_DISABLE_AUTO_UPDATE` | Disable automatic update checks (core + tray) | `false` |
119+
| `MCPPROXY_UPDATE_NOTIFY_ONLY` | Only notify about updates, don't auto-install (tray) | `false` |
120+
| `MCPPROXY_ALLOW_PRERELEASE_UPDATES` | Allow prerelease/beta version updates (core + tray) | `false` |
121+
| `MCPPROXY_UPDATE_APP_BUNDLE` | Enable app bundle updates (macOS tray) | `false` |
122+
123+
Update checking can also be controlled from the config file via the
124+
`update_check` block (`enabled`, `channel`) — see
125+
[Version Updates](/features/version-updates). When both are set, the
126+
environment variables **win** over the config keys.
122127

123128
### Setting Tray Variables on macOS
124129

docs/features/version-updates.md

Lines changed: 66 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ The sidebar displays the current version at the bottom. When an update is availa
3737
- A small "update available" badge appears next to the version
3838
- Click to view the release notes
3939

40+
The dashboard additionally shows a **dismissible update banner** ("Update
41+
available: vX — you are running vY") with a release-notes link. Dismissal is
42+
**per version**: dismissing the banner for v1.3.0 keeps it hidden for v1.3.0
43+
(persisted in the browser), but the banner reappears when a newer release
44+
becomes available. The banner is non-modal and never blocks the UI.
45+
4046
### CLI Doctor Command
4147

4248
The `mcpproxy doctor` command shows version information:
@@ -55,20 +61,75 @@ Download: https://github.com/smart-mcp-proxy/mcpproxy-go/releases/tag/v1.3.0
5561

5662
## Configuration
5763

64+
### Config File (`update_check`)
65+
66+
Update checking is controlled from `mcp_config.json` via the `update_check`
67+
block:
68+
69+
```json
70+
{
71+
"update_check": {
72+
"enabled": true,
73+
"channel": "stable"
74+
}
75+
}
76+
```
77+
78+
| Option | Type | Default | Description |
79+
|--------|------|---------|-------------|
80+
| `enabled` | boolean | `true` | Master switch. When `false`, no network check is performed (background poll and the manual re-check) and no upgrade nudge appears on any surface — the `update` object is omitted from `/api/v1/info`. |
81+
| `channel` | string | `"stable"` | Release channel: `"stable"` (GitHub `releases/latest`; prereleases never offered) or `"rc"` (prerelease tags such as `v0.47.0-rc.1` included). |
82+
83+
Both keys are **hot-reloadable**: editing the config file or applying it via
84+
`POST /api/v1/config/apply` takes effect without a restart. Re-enabling (or
85+
switching channels) triggers a prompt re-check instead of waiting for the next
86+
4-hour tick.
87+
88+
`enabled: false` also gates the Go tray's built-in daily self-update check, so
89+
no surface performs a network check while disabled. The tray does **not** read
90+
`mcp_config.json` itself (it holds no state); instead it asks the core via
91+
`GET /api/v1/info` before checking — the core omits the `update` object when
92+
update checking is disabled, and the tray then skips its own network check. If
93+
the core is unreachable the tray skips that tick and retries, rather than
94+
falling open to a check the operator may have disabled. The tray's own check
95+
still selects prereleases via `MCPPROXY_ALLOW_PRERELEASE_UPDATES` only —
96+
converging it fully onto the shared checker (including `channel`) is a separate
97+
Spec 079 work item (FR-001a).
98+
5899
### Environment Variables
59100

60101
| Variable | Description | Default |
61102
|----------|-------------|---------|
62103
| `MCPPROXY_DISABLE_AUTO_UPDATE` | Disable background update checks entirely | `false` |
63104
| `MCPPROXY_ALLOW_PRERELEASE_UPDATES` | Include prerelease/beta versions in update checks | `false` |
64105

106+
### Precedence (env vs config)
107+
108+
The environment switches **win over** the `update_check` config keys — they
109+
are the operator override:
110+
111+
- `MCPPROXY_DISABLE_AUTO_UPDATE=true` disables checking even when
112+
`update_check.enabled` is `true`.
113+
- `MCPPROXY_ALLOW_PRERELEASE_UPDATES=true` selects the prerelease channel even
114+
when `update_check.channel` is `"stable"`.
115+
116+
The env vars only widen in one direction (disable checks / include
117+
prereleases). They cannot re-enable checking that the config disabled: with
118+
`update_check.enabled: false`, no check runs regardless of environment.
119+
65120
### Examples
66121

67122
```bash
68-
# Disable update checking
123+
# Disable update checking (config file — persistent, hot-reloads)
124+
# "update_check": { "enabled": false }
125+
126+
# Disable update checking (environment — wins over config)
69127
MCPPROXY_DISABLE_AUTO_UPDATE=true mcpproxy serve
70128

71-
# Enable prerelease updates (for beta testers)
129+
# Opt in to prerelease (RC) updates via config
130+
# "update_check": { "channel": "rc" }
131+
132+
# Enable prerelease updates via environment (for beta testers)
72133
MCPPROXY_ALLOW_PRERELEASE_UPDATES=true mcpproxy serve
73134
```
74135

@@ -127,7 +188,7 @@ When running a development build (version shows as "development"), update checki
127188
### Update check not working
128189

129190
1. Ensure you have internet connectivity
130-
2. Check if `MCPPROXY_DISABLE_AUTO_UPDATE` is set
191+
2. Check if `MCPPROXY_DISABLE_AUTO_UPDATE` is set, or `update_check.enabled` is `false` in `mcp_config.json`
131192
3. Run `mcpproxy doctor` to see current version status
132193
4. Check logs for any GitHub API errors:
133194
```bash
@@ -136,7 +197,8 @@ When running a development build (version shows as "development"), update checki
136197

137198
### Prerelease not showing
138199

139-
By default, prerelease versions are excluded. To enable:
200+
By default, prerelease versions are excluded. To enable, set
201+
`"update_check": { "channel": "rc" }` in `mcp_config.json`, or:
140202

141203
```bash
142204
export MCPPROXY_ALLOW_PRERELEASE_UPDATES=true

docs/prerelease-builds.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ The GitHub release is created with `prerelease: true`, so it does **not** become
6969
- Does not deploy docs or trigger marketing automation (`deploy-docs`, `trigger-marketing-update` guarded).
7070
- Not offered as an update on **stable channels**:
7171
- The macOS tray uses GitHub `releases/latest`, which excludes prereleases (`native/macos/MCPProxy/MCPProxy/Services/UpdateService.swift`), plus a semver downgrade guard so an `-rc` is never treated as "newer" than the matching stable.
72-
- The backend/tray update check is stable-only by default (`internal/tray/tray.go``releases/latest`). Set `MCPPROXY_ALLOW_PRERELEASE_UPDATES=true` to opt in to RC update offers.
72+
- The backend/tray update check is stable-only by default (`internal/tray/tray.go``releases/latest`). Set `MCPPROXY_ALLOW_PRERELEASE_UPDATES=true` to opt in to RC update offers; the core checker can also opt in via `"update_check": { "channel": "rc" }` in `mcp_config.json` (Spec 079 — the Go tray's own self-update check gates on the core's decision by querying `GET /api/v1/info` rather than reading the config file, and selects prereleases via `MCPPROXY_ALLOW_PRERELEASE_UPDATES`; converging it fully onto the shared checker is FR-001a).
7373

7474
### Installing an RC
7575

0 commit comments

Comments
 (0)