Skip to content

fix(serve): read <data-dir>/mcp_config.json and implement MCPPROXY_DATA_DIR - #1694

Merged
Dumbris merged 7 commits into
smart-mcp-proxy:mainfrom
james-crowley:fix/serve-data-dir-config
Oct 22, 2026
Merged

Dumbris merged 7 commits into
smart-mcp-proxy:mainfrom
james-crowley:fix/serve-data-dir-config

Conversation

@james-crowley

Copy link
Copy Markdown
Contributor

Description

Fixes #1693.

serve now resolves its config the way the management commands already do (#854, #897, #908): an explicit --config wins, then <data-dir>/mcp_config.json when it exists, otherwise the legacy discovery (cwd, $HOME/.mcpproxy). On a first run with no config anywhere, the default (and its generated API key) is seeded inside the named data dir instead of under $HOME.

MCPPROXY_DATA_DIR, which the docs list but the code never read, now seeds --data-dir for every command (an explicit flag still wins). The legacy MCPPROXY_DATA keeps its meaning (relocates the data directory only) and loses when both are set. --help is unchanged when the variable is set.

Changes: cmd/mcpproxy/main.go (implicitDataDirConfigPath, used by loadConfig), cmd/mcpproxy/path_flag.go, internal/config/loader.go (EnvDataDir, EnvDataDirLegacy, DataDirFromEnv), docs (installation.md trap rewritten, env var tables, command reference) and a CHANGELOG entry.

Behaviour change, one case: an instance started with --data-dir X that relied on the legacy config while a stale X/mcp_config.json also exists now reads the one in X (noted in the CHANGELOG as a migration).

Verified with a built binary: a config with a fixed port and API key in the data dir is used through both --data-dir and MCPPROXY_DATA_DIR, nothing is created under a clean $HOME, and a first run seeds <data-dir>/mcp_config.json.

Testing

  • I have tested these changes locally
  • I have added/updated tests that prove my fix is effective or my feature works (cmd/mcpproxy/serve_data_dir_config_test.go: data-dir and env read the config, flag beats env, --config beats data dir, first run seeds in the data dir, legacy config kept when the data dir has none, env name precedence)
  • All existing tests pass (go test ./cmd/mcpproxy ./internal/config ./cmd/release-gate)

serve looked for mcp_config.json only in the working directory and
$HOME/.mcpproxy and applied --data-dir afterwards, while every management
command already read <data-dir>/mcp_config.json. serve now resolves the
config the same way: --config, then <data-dir>/mcp_config.json when it
exists, and on a first run the default is seeded in the data dir.
MCPPROXY_DATA_DIR, documented but never read, now seeds --data-dir; the legacy
MCPPROXY_DATA still only relocates the data directory and loses when both are
set.

Fixes smart-mcp-proxy#1693
@codecov-commenter

codecov-commenter commented Oct 20, 2026 •

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 96.00000% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
cmd/mcpproxy/main.go 93.75% 0 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

james-crowley and others added 3 commits October 20, 2026 08:34
… legacy-config fallback

A whitespace-only MCPPROXY_DATA_DIR set cfg.DataDir to the blank value and
shadowed MCPPROXY_DATA, because the env override read the raw variable
while DataDirFromEnv trims it. Both now go through the trimmed value.

Docs: the installation guide says what happens when the data dir has no
config but a legacy one exists, and the CHANGELOG notes that an already
exported MCPPROXY_DATA_DIR takes effect for the first time.

Related smart-mcp-proxy#1693
@Dumbris
Dumbris enabled auto-merge (squash) October 20, 2026 15:38
@Dumbris

Dumbris commented Oct 20, 2026

Copy link
Copy Markdown
Member

Thanks @james-crowley, this is a clean fix and the live checks (data-dir config, env-only, the packaged --config + --data-dir layout, and a first run) all behaved as described. I pushed one small commit on top of your branch: the env override now reads the trimmed MCPPROXY_DATA_DIR (a whitespace-only value used to set the data dir to blanks and shadow MCPPROXY_DATA), plus a clause in the installation guide about the legacy-config fallback and a CHANGELOG note that an already exported MCPPROXY_DATA_DIR now takes effect. Auto-merge is armed; it lands as soon as CI is green.

@james-crowley

Copy link
Copy Markdown
Contributor Author

CI on the current head (0a1fea5) is red, and I think none of it is a product problem, but I can't rerun jobs (no admin rights here), so flagging what I found:

  • Unit Tests (ubuntu, 1.26): failed in go mod download (proxy.golang.org ... go-porterstemmer@v1.0.3: INTERNAL_ERROR), before any test ran.
  • Build Binaries (windows/amd64): TestServeFirstRunSeedsConfigInDataDir failed on the temp-dir cleanup after the assertions (unlinkat ...\\002: The process cannot access the file because it is being used by another process, 4.05s). The assertions themselves passed and the other TestServe* tests in the same package passed. That looks like Windows holding the directory briefly, but I have not reproduced it. If it recurs on a rerun I will change that test.
  • Build Binaries (darwin amd64, windows arm64): ran to the 30 minute mark; the other darwin/linux builds failed or were cancelled with no test failure in the log I could see.

Could you rerun the failed jobs when convenient?

@Dumbris

Dumbris commented Oct 22, 2026

Copy link
Copy Markdown
Member

Pushed a merge of main onto your branch (the only conflict was the CHANGELOG, resolved as a union). No change to your code. That also gives CI a fresh run in place of the proxy and Windows temp-dir failures you flagged; merging once it is green.

Seeding a first-run config probes Docker with a docker info subprocess
under a 2 s timeout. On Windows a probe killed at the deadline can still
hold the test's working directory and fail t.TempDir cleanup, which is
the unlinkat failure CI showed on TestServeFirstRunSeedsConfigInDataDir.
@Dumbris

Dumbris commented Oct 22, 2026

Copy link
Copy Markdown
Member

One more small commit on your branch (5e182db): the serve data-dir tests now put an empty directory on PATH. Seeding a first-run config probes Docker with a docker info subprocess under a 2 s timeout, and on Windows a probe killed at the deadline can still hold the test's working directory, which is the unlinkat failure in TestServeFirstRunSeedsConfigInDataDir you flagged. No change to the code under test.

@Dumbris Dumbris left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified on a merge with main: build, CI lint config, race tests for cmd/mcpproxy and internal/config; cross-reviewed; live checks done earlier. The env-dir-must-exist behaviour matches the existing MCPPROXY_DATA semantics.

@Dumbris
Dumbris merged commit 1c51f74 into smart-mcp-proxy:main Oct 22, 2026
50 checks passed
@Dumbris

Dumbris commented Oct 22, 2026

Copy link
Copy Markdown
Member

Merged, and #1693 is closed with it. Thank you, @james-crowley! serve and the management commands finally agree on where the config lives, a first run seeds it inside the data dir instead of under $HOME, and MCPPROXY_DATA_DIR does what the docs have promised for a while. Thanks also for flagging the CI noise precisely instead of pushing blind reruns.

Contributions like this are what keep MCPProxy moving, and they matter a lot to the project.

One small ask, only if you feel like it: a short public note about your change (a tweet, a LinkedIn post, a line in a community you are part of) helps more people discover MCPProxy. No pressure at all, and I would be glad to repost it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: serve ignores <data-dir>/mcp_config.json (management commands read it), and MCPPROXY_DATA_DIR is documented but not implemented

3 participants