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:
Ross Masters
2025-02-28 23:03:30 +00:00
committed by GitHub
parent b84e7745f5
commit cc8a4fac87
2 changed files with 26 additions and 8 deletions

View File

@@ -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

View File

@@ -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,