feat: Allow passing through all environment variables to server (#27)
This PR adds the ability to pass through all environment variables to the server, using the flag `--pass-environment` (default off). This change allows a compose spec like this to access all environment variables from an env_file (as well as PATH): ```yaml server-brave-search: image: mcp-proxy:latest env_file: .brave.env # ENTRYPOINT from custom SSE-only image, for context entrypoint: ["mcp-proxy", "--sse-host=0.0.0.0", "--sse-port=8080", "--pass-environment", "--"] command: ["npx", "--yes", "@modelcontextprotocol/server-brave-search"] ``` The motivation behind this is I am developing in Docker Compose, with a custom client and multiple servers. I made a debian-based mcp-proxy image, with an entrypoint that set some SSE settings. When it came to adding brave search, I spent a bit of time struggling against var interpolation and an overridden entrypoint (cause: you can't access env vars in entrypoints, I think). I figured passing through all environment variables would be easier (and safe in a container). I started adding tests for this, but found myself refactoring \_\_main\_\_.py quite a bit to make it more testable. I've left that for now in the aim of an easy-to-review PR, but am happy to continue that effort if you'd like? Essentially breaking out the argument parser and the SSE client/server parts into functions and validating their config. Thanks again for this tool - it's made adding support for stdio servers in our client much easier! --------- Co-authored-by: Sergey Parfenyuk <myseverality@gmail.com>
This commit is contained in:
17
README.md
17
README.md
@@ -104,12 +104,13 @@ This mode requires the `--sse-port` argument to be set. The `--sse-host` argumen
|
||||
|
||||
Arguments
|
||||
|
||||
| Name | Required | Description | Example |
|
||||
| ---------------- | -------------------------- | ---------------------------------------------------------------- | -------------------- |
|
||||
| `command_or_url` | Yes | The command to spawn the MCP stdio server | uvx mcp-server-fetch |
|
||||
| `--sse-port` | No, random available | The SSE server port to listen on | 8080 |
|
||||
| `--sse-host` | No, `127.0.0.1` by default | The host IP address that the SSE server will listen on | 0.0.0.0 |
|
||||
| `--env` | No | Additional environment variables to pass to the MCP stdio server | FOO=BAR |
|
||||
| Name | Required | Description | Example |
|
||||
| -------------------- | -------------------------- | ---------------------------------------------------------------- | -------------------- |
|
||||
| `command_or_url` | Yes | The command to spawn the MCP stdio server | uvx mcp-server-fetch |
|
||||
| `--sse-port` | No, random available | The SSE server port to listen on | 8080 |
|
||||
| `--sse-host` | No, `127.0.0.1` by default | The host IP address that the SSE server will listen on | 0.0.0.0 |
|
||||
| `--env` | No | Additional environment variables to pass to the MCP stdio server | FOO=BAR |
|
||||
| `--pass-environment` | No | Pass through all environment variables when spawning the server | --no-pass-environment |
|
||||
|
||||
### 2.2 Example usage
|
||||
|
||||
@@ -181,7 +182,7 @@ docker run -t ghcr.io/sparfenyuk/mcp-proxy:v0.3.2-alpine --help
|
||||
## Command line arguments
|
||||
|
||||
```bash
|
||||
usage: mcp-proxy [-h] [-H KEY VALUE] [-e KEY VALUE] [--sse-port SSE_PORT] [--sse-host SSE_HOST] [command_or_url] [args ...]
|
||||
usage: mcp-proxy [-h] [-H KEY VALUE] [-e KEY VALUE] [--sse-port SSE_PORT] [--sse-host SSE_HOST] [--pass-environment] [command_or_url] [args ...]
|
||||
|
||||
Start the MCP proxy in one of two possible modes: as an SSE or stdio client.
|
||||
|
||||
@@ -199,6 +200,8 @@ stdio client options:
|
||||
args Any extra arguments to the command to spawn the server
|
||||
-e KEY VALUE, --env KEY VALUE
|
||||
Environment variables used when spawning the server. Can be used multiple times.
|
||||
--pass-environment, --no-pass-environment
|
||||
Pass through all environment variables when spawning the server.
|
||||
|
||||
SSE server options:
|
||||
--sse-port SSE_PORT Port to expose an SSE server on. Default is a random port
|
||||
|
||||
@@ -77,6 +77,12 @@ def main() -> None:
|
||||
help="Environment variables used when spawning the server. Can be used multiple times.",
|
||||
default=[],
|
||||
)
|
||||
stdio_client_options.add_argument(
|
||||
"--pass-environment",
|
||||
action=argparse.BooleanOptionalAction,
|
||||
help="Pass through all environment variables when spawning the server.",
|
||||
default=False,
|
||||
)
|
||||
|
||||
sse_server_group = parser.add_argument_group("SSE server options")
|
||||
sse_server_group.add_argument(
|
||||
@@ -112,10 +118,19 @@ def main() -> None:
|
||||
|
||||
# Start a client connected to the given command, and expose as an SSE server
|
||||
logging.debug("Starting stdio client and SSE server")
|
||||
|
||||
# The environment variables passed to the server process
|
||||
env: dict[str, str] = {}
|
||||
# Pass through current environment variables if configured
|
||||
if args.pass_environment:
|
||||
env.update(os.environ)
|
||||
# Pass in and override any environment variables with those passed on the command line
|
||||
env.update(dict(args.env))
|
||||
|
||||
stdio_params = StdioServerParameters(
|
||||
command=args.command_or_url,
|
||||
args=args.args,
|
||||
env=dict(args.env),
|
||||
env=env,
|
||||
)
|
||||
sse_settings = SseServerSettings(
|
||||
bind_host=args.sse_host,
|
||||
|
||||
Reference in New Issue
Block a user