Skip to content

Commit bdadb93

Browse files
committed
feature: oauth login
1 parent 444406d commit bdadb93

File tree

13 files changed

+1488
-128
lines changed

13 files changed

+1488
-128
lines changed

README.md

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Note: There is also a work-in-progress TypeScript implementation available in a
1111
## Key Features
1212

1313
- **Galaxy Connection**: Connect to any Galaxy instance with a URL and API key
14+
- **OAuth Login (optional)**: Offer browser-based sign-in that exchanges credentials for temporary Galaxy API keys
1415
- **Server Information**: Retrieve comprehensive server details including version, configuration, and capabilities
1516
- **Tools Management**: Search, view details, and execute Galaxy tools
1617
- **Workflow Integration**: Access and import workflows from the Interactive Workflow Composer (IWC)
@@ -20,36 +21,65 @@ Note: There is also a work-in-progress TypeScript implementation available in a
2021

2122
## Quick Start
2223

23-
The fastest way to get started is using `uvx`:
24+
The `galaxy-mcp` CLI ships with both stdio (local) and HTTP transports. Choose the setup that
25+
matches your client:
2426

2527
```bash
26-
# Run the server directly without installation
28+
# Stdio transport (default) – great for local development tools
2729
uvx galaxy-mcp
2830

29-
# Run with MCP developer tools for interactive exploration
30-
uvx --from galaxy-mcp mcp dev galaxy_mcp.server
31-
32-
# Run as a deployed MCP server
33-
uvx --from galaxy-mcp mcp run galaxy_mcp.server
31+
# HTTP transport with OAuth (for remote/browser clients)
32+
export GALAXY_URL="https://usegalaxy.org.au/" # Target Galaxy instance
33+
export GALAXY_MCP_PUBLIC_URL="https://mcp.example.com" # Public base URL for OAuth redirects
34+
export GALAXY_MCP_SESSION_SECRET="$(openssl rand -hex 32)"
35+
uvx galaxy-mcp --transport streamable-http --host 0.0.0.0 --port 8000
3436
```
3537

36-
You'll need to set up your Galaxy credentials via environment variables:
38+
When running over stdio you can provide long-lived credentials via environment variables:
3739

3840
```bash
39-
export GALAXY_URL=<galaxy_url>
40-
export GALAXY_API_KEY=<galaxy_api_key>
41+
export GALAXY_URL="https://usegalaxy.org/"
42+
export GALAXY_API_KEY="your-api-key"
4143
```
4244

45+
For OAuth flows the server exchanges user credentials for short-lived Galaxy API keys on demand, so
46+
you typically leave `GALAXY_API_KEY` unset.
47+
4348
### Alternative Installation
4449

4550
```bash
4651
# Install from PyPI
4752
pip install galaxy-mcp
4853

49-
# Or from source
54+
# Run (stdio by default)
55+
galaxy-mcp
56+
57+
# Or from source using uv
5058
cd mcp-server-galaxy-py
51-
pip install -r requirements.txt
52-
mcp run main.py
59+
uv sync
60+
uv run galaxy-mcp --transport streamable-http --host 0.0.0.0 --port 8000
61+
```
62+
63+
## Container Usage
64+
65+
The published image defaults to stdio transport (no HTTP listener):
66+
67+
```bash
68+
docker run --rm -it \
69+
-e GALAXY_URL="https://usegalaxy.org/" \
70+
-e GALAXY_API_KEY="your-api-key" \
71+
galaxyproject/galaxy-mcp
72+
```
73+
74+
For OAuth + HTTP:
75+
76+
```bash
77+
docker run --rm -it -p 8000:8000 \
78+
-e GALAXY_URL="https://usegalaxy.org.au/" \
79+
-e GALAXY_MCP_TRANSPORT="streamable-http" \
80+
-e GALAXY_MCP_PUBLIC_URL="https://mcp.example.com" \
81+
-e GALAXY_MCP_SESSION_SECRET="$(openssl rand -hex 32)" \
82+
galaxyproject/galaxy-mcp
5383
```
5484

5585
## Development Guidelines

mcp-server-galaxy-py/Dockerfile

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,12 @@ RUN groupadd -r app && useradd -r -g app app
4141

4242
WORKDIR /app
4343

44-
# Define default environment variables
45-
ENV GALAXY_INSTANCE="https://usegalaxy.org" \
46-
GALAXY_API_KEY=""
44+
# Define default environment variables (stdio transport by default)
45+
ENV GALAXY_URL="https://usegalaxy.org" \
46+
GALAXY_API_KEY="" \
47+
GALAXY_MCP_TRANSPORT="stdio" \
48+
GALAXY_MCP_HOST="0.0.0.0" \
49+
GALAXY_MCP_PORT="8000"
4750

4851
COPY --from=uv /root/.local /root/.local
4952
COPY --from=uv --chown=app:app /app/.venv /app/.venv
@@ -63,12 +66,12 @@ USER app
6366
# Expose service port
6467
EXPOSE 8000
6568

66-
# Add healthcheck
69+
# Add healthcheck that verifies the HTTP listener is accepting connections
6770
HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \
68-
CMD mcp-server-galaxy --health-check || exit 1
71+
CMD python -c "import os, socket, sys; addr=('127.0.0.1', int(os.environ.get('GALAXY_MCP_PORT', '8000'))); sock=socket.socket(); sock.settimeout(2); sock.connect(addr); sock.close()"
6972

7073
# Use tini as init to handle signals properly
7174
ENTRYPOINT ["/usr/bin/tini", "--"]
7275

73-
# Update command to use environment variables instead of DB path
74-
CMD ["mcp-server-galaxy", "--galaxy-url", "${GALAXY_INSTANCE}", "--api-key", "${GALAXY_API_KEY}"]
76+
# Start the MCP server (transport/host/port taken from environment variables)
77+
CMD ["galaxy-mcp"]

mcp-server-galaxy-py/README.md

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ This is the Python implementation of the Galaxy MCP server, providing a Model Co
55
## Features
66

77
- Complete Galaxy API integration through BioBlend
8+
- Optional OAuth login flow for HTTP deployments
89
- Interactive Workflow Composer (IWC) integration
910
- FastMCP2 server with remote deployment support
1011
- Type-annotated Python codebase
@@ -39,54 +40,65 @@ uv sync --all-extras
3940

4041
## Configuration
4142

42-
The server requires Galaxy credentials to connect to an instance. You can provide these via environment variables:
43+
At minimum the server needs to know which Galaxy instance to target:
4344

4445
```bash
45-
export GALAXY_URL=<galaxy_url>
46-
export GALAXY_API_KEY=<galaxy_api_key>
46+
export GALAXY_URL="https://usegalaxy.org.au/"
4747
```
4848

49-
Alternatively, create a `.env` file in the project root with these variables.
49+
How you authenticate depends on your transport:
5050

51-
## Usage
51+
- **Stdio / long-lived sessions** – provide an API key:
52+
53+
```bash
54+
export GALAXY_API_KEY="your-api-key"
55+
```
56+
57+
- **HTTP / OAuth** – configure the public URL that users reach and a signing secret for session
58+
tokens. The server mints short-lived Galaxy API keys on behalf of each user.
5259

53-
### Quick Start with uvx
60+
```bash
61+
export GALAXY_MCP_PUBLIC_URL="https://mcp.example.com"
62+
export GALAXY_MCP_SESSION_SECRET="$(openssl rand -hex 32)"
63+
```
5464

55-
The fastest way to run the Galaxy MCP server is using `uvx`:
65+
Optionally set `GALAXY_MCP_CLIENT_REGISTRY` to control where OAuth client registrations are stored.
66+
67+
You can also steer the transport with `GALAXY_MCP_TRANSPORT` (`stdio`, `streamable-http`, or `sse`).
68+
All variables can be placed in a `.env` file for convenience.
69+
70+
## Usage
71+
72+
### Quick Start with `uvx`
5673

5774
```bash
58-
# Run the server directly without installation
75+
# Local stdio transport (no network listener)
5976
uvx galaxy-mcp
6077

61-
# Run with FastMCP2 dev tools
62-
uvx --from galaxy-mcp fastmcp dev src/galaxy_mcp/server.py
63-
64-
# Run as remote server
65-
uvx --from galaxy-mcp fastmcp run src/galaxy_mcp/server.py --transport sse --port 8000
78+
# Remote/browser clients with HTTP + OAuth
79+
export GALAXY_URL="https://usegalaxy.org.au/"
80+
export GALAXY_MCP_PUBLIC_URL="https://mcp.example.com"
81+
export GALAXY_MCP_SESSION_SECRET="$(openssl rand -hex 32)"
82+
uvx galaxy-mcp --transport streamable-http --host 0.0.0.0 --port 8000
6683
```
6784

68-
### As a standalone MCP server
85+
### Installed CLI
6986

7087
```bash
71-
# Install and run the MCP server
7288
pip install galaxy-mcp
73-
galaxy-mcp
74-
75-
# The server will wait for MCP protocol messages on stdin
89+
galaxy-mcp --transport streamable-http --host 0.0.0.0 --port 8000
7690
```
7791

78-
### With MCP clients
92+
If `--transport` is omitted the server defaults to stdio and reads/writes MCP messages via stdin/stdout.
7993

80-
```bash
81-
# Use with FastMCP2 CLI tools
82-
fastmcp dev src/galaxy_mcp/server.py
83-
fastmcp run src/galaxy_mcp/server.py
94+
### Working from a checkout
8495

85-
# Use with other MCP-compatible clients
86-
your-mcp-client galaxy-mcp
96+
```bash
97+
uv sync
98+
uv run galaxy-mcp --transport streamable-http --host 0.0.0.0 --port 8000
8799
```
88100

89-
See [USAGE_EXAMPLES.md](USAGE_EXAMPLES.md) for detailed usage patterns and common examples.
101+
See [USAGE_EXAMPLES.md](USAGE_EXAMPLES.md) for detailed tool usage patterns.
90102

91103
## Available MCP Tools
92104

mcp-server-galaxy-py/USAGE_EXAMPLES.md

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,25 @@ This document provides common usage patterns and examples for the Galaxy MCP ser
66

77
### 1. Connect to Galaxy
88

9-
First, you need to establish a connection to your Galaxy instance:
9+
For stdio deployments you can authenticate with a long-lived API key:
1010

1111
```python
12-
# Option 1: Use environment variables (recommended)
1312
# Set GALAXY_URL and GALAXY_API_KEY in your environment or .env file
1413
connect()
1514

16-
# Option 2: Provide credentials directly
15+
# Or provide credentials directly
1716
connect(url="https://your-galaxy-instance.org", api_key="your-api-key")
1817
```
1918

19+
For HTTP deployments that use OAuth the active session is resolved automatically. Calling
20+
`connect()` without arguments simply confirms the session and returns user details:
21+
22+
```python
23+
session_info = connect()
24+
assert session_info["auth"] == "oauth"
25+
print(session_info["user"]["username"])
26+
```
27+
2028
#### Get server information
2129

2230
Once connected, you can retrieve comprehensive information about the Galaxy server:

mcp-server-galaxy-py/pyproject.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ classifiers = [
2626
]
2727
requires-python = ">=3.10"
2828
dependencies = [
29+
"anyio>=4.0.0",
2930
"bioblend>=1.5.0",
31+
"cryptography>=41.0.0",
3032
"fastmcp>=2.3.0",
3133
"requests>=2.32.3",
3234
"python-dotenv>=1.0.0",

mcp-server-galaxy-py/src/galaxy_mcp/__main__.py

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,41 @@
11
"""Command-line entry point for Galaxy MCP server."""
22

3+
import argparse
4+
import os
5+
36
from . import server
47

58

6-
def run():
7-
"""Run the MCP server."""
8-
# Use FastMCP's simplified run method
9-
server.mcp.run()
9+
def run() -> None:
10+
"""Run the MCP server using stdio or HTTP transport."""
11+
parser = argparse.ArgumentParser(description="Run the Galaxy MCP server.")
12+
parser.add_argument(
13+
"--transport",
14+
choices=["stdio", "streamable-http", "sse"],
15+
help="Transport to use (defaults to environment or stdio).",
16+
)
17+
parser.add_argument("--host", help="HTTP host to bind when using HTTP transports.")
18+
parser.add_argument(
19+
"--port",
20+
type=int,
21+
help="HTTP port to bind when using HTTP transports.",
22+
)
23+
parser.add_argument(
24+
"--path",
25+
help="Optional HTTP path when using streamable transports.",
26+
)
27+
args = parser.parse_args()
28+
29+
selected = (args.transport or os.environ.get("GALAXY_MCP_TRANSPORT") or "stdio").lower()
30+
if selected in {"streamable-http", "sse"}:
31+
server.run_http_server(
32+
host=args.host,
33+
port=args.port,
34+
transport=selected,
35+
path=args.path,
36+
)
37+
else:
38+
server.mcp.run()
1039

1140

1241
if __name__ == "__main__":

0 commit comments

Comments
 (0)