Fix: mcp config: readd support for file secrets#2476
Fix: mcp config: readd support for file secrets#2476malikwirin wants to merge 2 commits intocharmbracelet:mainfrom
Conversation
Introduces the env_files config key that maps environment variable names to file paths. README updated with usage example and description.
Adds env_files to MCPConfig, mapping env var names to file paths. Crush reads the file contents at startup and injects them as environment variables when spawning the MCP server process
|
All contributors have signed the CLA ✍️ ✅ |
|
I have read the Contributor License Agreement (CLA) and hereby sign the CLA. |
|
Currently getting the following error in real tests |
No this error happened because my crush config was cached inside Everything worked out great. Was validating everything somewhat like this: mkdir ~/crush-test && cd ~/crush-test
echo "my-test-token" > ~/test-token
cat > print-env.sh <<'EOF'
#!/usr/bin/env bash
env | grep MY_TOKEN >> ~/crush-test/mcp-env.log 2>&1
sleep 10
EOF
chmod +x print-env.sh
cat > crush.json <<'EOF'
{
"mcp": {
"test-server": {
"type": "stdio",
"command": "/home/malik/crush-test/print-env.sh",
"env_files": {
"MY_TOKEN": "/home/malik/test-token"
}
}
}
}
EOF
cat ./mcp-env.log
MY_TOKEN=my-test-token |
andreynering
left a comment
There was a problem hiding this comment.
Hi @malikwirin,
I actually think that the right approach is to actually to restore the shell expansion functionality we had before, and not add env_files.
Do you agree? A separate PR with that would be welcome.
I think the shell expansion functionality has been dropped for security reasons? Can you maybe point me to the PRs that introduced the regression? |
Problem
MCP servers that require secrets (e.g. API tokens) currently rely on environment variable expansion via
$(echo $VAR)syntax, which spawns a shell process. This makes it cumbersome to use file-based secret management tools like sops, systemd credentials, or Docker secrets.Closes #2334
Solution
Adds a new
env_filesfield toMCPConfigthat maps environment variable names to file paths. Crush reads the file contents at startup and injects them as environment variables when spawning the MCP server process{ "mcp": { "codeberg": { "type": "stdio", "command": "/path/to/forgejo-mcp", "args": ["transport", "stdio", "--url", "https://codeberg.org"], "env_files": { "FORGEJO_ACCESS_TOKEN": "/run/secrets/codeberg_token" } } } }Changes
EnvFiles map[string]stringtoMCPConfiginconfig.goresolveEnvFiles()helper that reads file contents and trims trailing newlinesMCPConfig.ResolvedEnv()to mergeenvandenv_filesREADME.mdwith a usage exampleNotes
If the same variable is set in both
envandenv_files, both entries will be present in the resulting slice. The last-wins behavior ofos/execmeansenv_filestakes precedence in practice. This is documented viaTestMCPConfig_ResolvedEnv_DuplicateKeyEnvWins.CONTRIBUTING.md.