MCP Stdio Bridge
A generic, professional-grade gateway that bridges Model Context Protocol (MCP) servers between SSE (Server-Sent Events) and Stdio transports.
Features
-
Generic Bridge: Works with any executable that speaks MCP over stdio.
-
Command Wrapper Mode: Directly wrap any CLI utility (like
wp-cli,git, or custom scripts) into a restricted MCP server without writing external scripts. -
Dual Transport Support: Run over SSE (HTTP/HTTPS) for remote access or Stdio for local use by MCP clients.
-
100% Test Coverage: Exhaustive test suite ensuring stability across all transports, operational modes, and failure paths.
-
YAML Configuration: Easily manage settings via a central config file.
-
Dynamic Configuration Reload: Opt-in feature to live-reload settings from
config.yamlwithout dropping active sessions — via the--watch-configfile watcher or by sendingSIGHUPon POSIX systems. -
Daemon Mode:
--daemonizeperforms a POSIX double-fork to detach from the terminal; pair with--pid-filefor init system and supervisor integration. -
Idle Session Timeouts: Automatically terminates stalled proxy and wrapper sessions to prevent resource leaks.
-
Process Management: Automatically spawns, manages, and cleans up subprocesses for bridging.
-
Security:
- API key authentication (Header or Query Param).
- Restricted argument prefixing and regex filtering for wrapped commands.
- Built-in Directory Traversal Protection for local tool execution.
- Environment Scrubbing: Allowlist/Denylist variables passed to subprocesses.
- Secret Masking: Sensitive keys are automatically hidden from logs.
- Connection limiting and message size throttling.
- SSL/TLS with client certificate and CRL support.
- HSTS and secure security headers.
Installation
Install the package using pip:
pip install mcp-stdio-bridge
Documentation
For detailed information on configuring and deploying the bridge, see:
- docs/configuration.md: Full settings reference and JSON Schema.
- docs/deployment.md: Docker and local execution guides.
- docs/mcp-servers.md: Integration requirements for MCP servers.
- docs/roadmap.md: Future considerations and planned features.
Architecture & Design
To understand the internal logic and security model, refer to:
- docs/architecture.md: Modular structure and transport/mode design.
- docs/security.md: Detailed security features and sandboxing.
- docs/workflows.md: Sequential operational flows.
Examples
Check the examples/ directory for templates covering common use cases:
wp-cli-wrapper.yaml: Manage WordPress via MCP (Mix of Allowlist/Denylist).git-wrapper.yaml: Expose Git operations to local clients (Allowlist-only).sqlite-proxy.yaml: Bridge an existing SQLite MCP server to SSE.security-patterns.yaml: Advanced regex-based security filtering.docker-tool-wrapper.yaml: Using custom environment variables per tool.
Example config.yaml:
host: "127.0.0.1"
port: 8000
command: "python your_mcp_server.py"
verbose: true
api_key: "your-secret-key"
max_connections: 5
cors_origins: ["*"]
# ssl_keyfile: "path/to/key.pem"
# ssl_certfile: "path/to/cert.pem"
Running the Bridge
mcp-stdio-bridge
Docker
You can run the bridge using Docker:
# Build the image
docker build -t mcp-stdio-bridge .
# Run with a mounted config file
docker run -p 8000:8000 -v $(pwd)/config.yaml:/app/config.yaml mcp-stdio-bridge
Alternatively, use Docker Compose:
docker-compose up -d
Customization Arguments
| Argument | Description | Default |
|---|---|---|
--host |
Host to bind the server to | 0.0.0.0 |
--port |
Port to bind the server to | 8000 |
--command |
The command to run for each session (Proxy Mode) | None |
--mode |
Operation mode (proxy or command-wrapper) |
proxy |
--transport |
Transport protocol (sse or stdio) |
sse |
--api-key |
Optional API key for authentication | None |
--max-connections |
Max concurrent subprocesses | 10 |
--max-message-size |
Max message size in bytes | 1048576 |
--ssl-keyfile |
Path to SSL key file | None |
--ssl-certfile |
Path to SSL cert file | None |
--ssl-keyfile-password |
Password for SSL key file | None |
--ssl-ca-certs |
Path to SSL CA certificates file | None |
--ssl-crlfile |
Path to SSL CRL file | None |
--ssl-client-cert-required |
Require client certificates | False |
--ssl-protocol |
SSL protocol (TLSv1_2, TLSv1_3) |
TLSv1_2 |
--ssl-ciphers |
SSL ciphers | None |
--hsts |
Enable HSTS | False |
--no-security-headers |
Disable default security headers | False |
--cors-origins |
CORS origins (space-separated) | ["*"] |
--idle-timeout |
Idle timeout for proxy sessions (seconds) | 3600 |
--cwd |
Global working directory for all subprocesses | None |
--max-retries |
Max subprocess restart attempts in proxy mode (0 = disabled) | 0 |
--retry-delay |
Initial delay between retries in seconds | 1.0 |
--retry-max-delay |
Maximum retry delay cap in seconds | 60.0 |
--retry-multiplier |
Exponential backoff growth factor | 2.0 |
--env-allowlist |
Allowlist of environment variables | None |
--env-denylist |
Denylist of environment variables | [...] |
--logging-level |
Set the logging level (DEBUG, INFO, etc.) | INFO |
--logging-config |
Path to a custom logging config file | None |
--watch-config |
Enable dynamic config reloading | False |
--rate-limit-requests |
Max requests per client per window (0 = disabled) | 0 |
--rate-limit-window |
Rate limit window size in seconds | 60 |
--version |
Display the application version and exit | |
-v, --verbose |
Enable verbose logging | False |
--generate-api-key |
Print a random URL-safe API key and exit | |
--generate-config |
Print a minimal YAML config built from the supplied CLI flags and exit | |
--generate-client-config |
Generate a JSON config snippet for an MCP client and exit (choices: claude-desktop, claude-code, cursor, gemini, vscode, copilot) |
|
-o, --output |
Write --generate-client-config output to FILE instead of stdout |
|
--pid-file FILE |
Write the process PID to FILE on startup; removed on clean exit or crash | |
--daemonize, -D |
Detach from the terminal and run as a daemon (POSIX only; incompatible with stdio transport) | False |
--reload |
Send SIGHUP to a running bridge identified by --pid-file and exit (POSIX only) |
|
--check-config |
Validate configuration and exit (like nginx -t) |
|
--warnings-as-errors |
Treat config warnings as errors (use with --check-config) |
Note: When operating in Stdio transport mode, all non-JSON-RPC output (including warnings, errors, and informational logs) is directed to
sys.stderrto maintain JSON-RPC stream integrity.
Development
Install all dependencies (including test and dev extras):
pip install -e ".[dev,test]"
Run the full test suite (the --timeout=10 flag is required — SSE transport tests can hang without it):
pytest --timeout=10
Lint, type-check, and security scan:
ruff check src tests
mypy src
bandit -r src -c pyproject.toml
Standalone Integration Tests
End-to-end integration tests live in standalone_tests/. They exercise real transport
and subprocess paths outside the unit-test harness, including SSH and Docker scenarios.
See docs/deployment.md for full
usage instructions.
# Quick local smoke test (no Docker required)
./standalone_tests/run_tests.sh
License
This is free and unencumbered software released into the public domain. For more information, please refer to the LICENSE file or http://unlicense.org/.
Metadata
Release files for mcp-stdio-bridge 1.5.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| mcp_stdio_bridge-1.5.0.tar.gz | 51.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mcp_stdio_bridge-1.5.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 83.4 kB
Release files / mcp_stdio_bridge-1.5.0.tar.gz
| Download URL | mcp_stdio_bridge-1.5.0.tar.gz |
|---|---|
| Size | 51.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9bd41339114f5ab60be38e01b7c57493e5867861465528f53660575f301edeab
|
|
BLAKE2b-256 checksum How to use checksums |
6c02813b72d9f0b3cc886019dfba68a968b63d05ce6535166065d7523abea0f9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 1, 2026.
Transparency logRelease files / mcp_stdio_bridge-1.5.0-py3-none-any.whl
| Download URL | mcp_stdio_bridge-1.5.0-py3-none-any.whl |
|---|---|
| Size | 32.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f57e4efcb7cac7aa41906f09aeffe054df345c0282d8c257e0ed4d8938baa35d
|
|
BLAKE2b-256 checksum How to use checksums |
447c214f3feccd61ca1767e86e6b13c5a0ff0b9d4fecda169098a955a7d73fcd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 1, 2026.
Transparency log