Skip to content

Commit 1de8394

Browse files
feat: support 'headers' argument for SSE server connection (sparfenyuk#23)
I have replaced the `--api-access-token` argument with the more generic `--headers` argument for SSE. This will allow for other auth mechanisms such as api keys as well. Intended usage: ```sh # API key mcp-proxy http://example.io/sse --headers x-api-key my-super-secret-api-key # Bearer token mcp-proxy http://example.io/sse --headers Authorization 'Bearer my-super-secret-bearer-token' # Multiple headers mcp-proxy http://example.io/sse --headers Authorization 'Bearer my-super-secret-bearer-token' --headers x-api-key my-super-secret-api-key ```
1 parent da9cbf7 commit 1de8394

File tree

3 files changed

+32
-31
lines changed

3 files changed

+32
-31
lines changed

README.md

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -51,16 +51,16 @@ This mode requires passing the URL to the MCP Server SSE endpoint as the first a
5151

5252
Arguments
5353

54-
| Name | Required | Description | Example |
55-
| -------------------- | -------- | --------------------------------------------------------------------- | --------------------- |
56-
| `command_or_url` | Yes | The MCP server SSE endpoint to connect to | http://example.io/sse |
57-
| `--api-access-token` | No | Will be sent as a `Bearer` access token in the `Authorization` header | YOUR_TOKEN |
54+
| Name | Required | Description | Example |
55+
| -------------------- | -------- | --------------------------------------------------------------------- | ----------------------------------------------|
56+
| `command_or_url` | Yes | The MCP server SSE endpoint to connect to | http://example.io/sse |
57+
| `--headers` | No | Headers to use for the MCP server SSE connection | Authorization 'Bearer my-secret-access-token' |
5858

5959
Environment Variables
6060

61-
| Name | Required | Description | Example |
62-
| ------------------ | -------- | ------------------------------------------- | ---------- |
63-
| `API_ACCESS_TOKEN` | No | Can be used instead of `--api-access-token` | YOUR_TOKEN |
61+
| Name | Required | Description | Example |
62+
| ------------------ | -------- | ---------------------------------------------------------------------------- | ---------- |
63+
| `API_ACCESS_TOKEN` | No | Can be used instead of `--headers Authorization 'Bearer <API_ACCESS_TOKEN>'` | YOUR_TOKEN |
6464

6565
### 1.2 Example usage
6666

@@ -181,32 +181,32 @@ docker run -t ghcr.io/sparfenyuk/mcp-proxy:v0.3.2-alpine --help
181181
## Command line arguments
182182

183183
```bash
184-
usage: mcp-proxy [-h] [--api-access-token API_ACCESS_TOKEN] [-e KEY VALUE] [--sse-port SSE_PORT] [--sse-host SSE_HOST] [command_or_url] [args ...]
184+
usage: mcp-proxy [-h] [-H KEY VALUE] [-e KEY VALUE] [--sse-port SSE_PORT] [--sse-host SSE_HOST] [command_or_url] [args ...]
185185

186-
Start the MCP proxy in one of two possible modes: as a SSE or stdio client.
186+
Start the MCP proxy in one of two possible modes: as an SSE or stdio client.
187187

188188
positional arguments:
189-
command_or_url Command or URL to connect to. When a URL, will run a SSE client, otherwise will run the given command and connect as a stdio client. See corresponding options for more details.
189+
command_or_url Command or URL to connect to. When a URL, will run an SSE client, otherwise will run the given command and connect as a stdio client. See corresponding options for more details.
190190

191191
options:
192192
-h, --help show this help message and exit
193193

194194
SSE client options:
195-
--api-access-token API_ACCESS_TOKEN
196-
Access token Authorization header passed by the client to the SSE server. Can also be set as environment variable API_ACCESS_TOKEN.
195+
-H KEY VALUE, --headers KEY VALUE
196+
Headers to pass to the SSE server. Can be used multiple times.
197197

198198
stdio client options:
199199
args Any extra arguments to the command to spawn the server
200200
-e KEY VALUE, --env KEY VALUE
201201
Environment variables used when spawning the server. Can be used multiple times.
202202

203203
SSE server options:
204-
--sse-port SSE_PORT Port to expose a SSE server on. Default is a random port
205-
--sse-host SSE_HOST Host to expose a SSE server on. Default is 127.0.0.1
204+
--sse-port SSE_PORT Port to expose an SSE server on. Default is a random port
205+
--sse-host SSE_HOST Host to expose an SSE server on. Default is 127.0.0.1
206206

207207
Examples:
208208
mcp-proxy http://localhost:8080/sse
209-
mcp-proxy --api-access-token YOUR_TOKEN http://localhost:8080/sse
209+
mcp-proxy --headers Authorization 'Bearer YOUR_TOKEN' http://localhost:8080/sse
210210
mcp-proxy --sse-port 8080 -- your-command --arg1 value1 --arg2 value2
211211
mcp-proxy your-command --sse-port 8080 -e KEY VALUE -e ANOTHER_KEY ANOTHER_VALUE
212212
```

src/mcp_proxy/__main__.py

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@
2222
SSE_URL: t.Final[str | None] = os.getenv(
2323
"SSE_URL",
2424
None,
25-
) # Left for backwards compatibility. Will be removed in future.
26-
API_ACCESS_TOKEN: t.Final[str | None] = os.getenv("API_ACCESS_TOKEN", None)
25+
)
2726

2827

2928
def main() -> None:
@@ -35,7 +34,7 @@ def main() -> None:
3534
epilog=(
3635
"Examples:\n"
3736
" mcp-proxy http://localhost:8080/sse\n"
38-
" mcp-proxy --api-access-token YOUR_TOKEN http://localhost:8080/sse\n"
37+
" mcp-proxy --headers Authorization 'Bearer YOUR_TOKEN' http://localhost:8080/sse\n"
3938
" mcp-proxy --sse-port 8080 -- your-command --arg1 value1 --arg2 value2\n"
4039
" mcp-proxy your-command --sse-port 8080 -e KEY VALUE -e ANOTHER_KEY ANOTHER_VALUE\n"
4140
),
@@ -54,12 +53,13 @@ def main() -> None:
5453

5554
sse_client_group = parser.add_argument_group("SSE client options")
5655
sse_client_group.add_argument(
57-
"--api-access-token",
58-
default=API_ACCESS_TOKEN,
59-
help=(
60-
"Access token Authorization header passed by the client to the SSE "
61-
"server. Can also be set as environment variable API_ACCESS_TOKEN."
62-
),
56+
"-H",
57+
"--headers",
58+
nargs=2,
59+
action="append",
60+
metavar=("KEY", "VALUE"),
61+
help="Headers to pass to the SSE server. Can be used multiple times.",
62+
default=[],
6363
)
6464

6565
stdio_client_options = parser.add_argument_group("stdio client options")
@@ -104,7 +104,10 @@ def main() -> None:
104104
):
105105
# Start a client connected to the SSE server, and expose as a stdio server
106106
logging.debug("Starting SSE client and stdio server")
107-
asyncio.run(run_sse_client(args.command_or_url, api_access_token=API_ACCESS_TOKEN))
107+
headers = dict(args.headers)
108+
if api_access_token := os.getenv("API_ACCESS_TOKEN", None):
109+
headers["Authorization"] = f"Bearer {api_access_token}"
110+
asyncio.run(run_sse_client(args.command_or_url, headers=headers))
108111
return
109112

110113
# Start a client connected to the given command, and expose as an SSE server

src/mcp_proxy/sse_client.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,22 @@
11
"""Create a local server that proxies requests to a remote server over SSE."""
22

3+
from typing import Any
4+
35
from mcp.client.session import ClientSession
46
from mcp.client.sse import sse_client
57
from mcp.server.stdio import stdio_server
68

79
from .proxy_server import create_proxy_server
810

911

10-
async def run_sse_client(url: str, api_access_token: str | None = None) -> None:
12+
async def run_sse_client(url: str, headers: dict[str, Any] | None = None) -> None:
1113
"""Run the SSE client.
1214
1315
Args:
1416
url: The URL to connect to.
15-
api_access_token: The API access token to use for authentication.
17+
headers: Headers for connecting to MCP server.
1618
1719
"""
18-
headers = {}
19-
if api_access_token is not None:
20-
headers["Authorization"] = f"Bearer {api_access_token}"
21-
2220
async with sse_client(url=url, headers=headers) as streams, ClientSession(*streams) as session:
2321
app = await create_proxy_server(session)
2422
async with stdio_server() as (read_stream, write_stream):

0 commit comments

Comments
 (0)