Skip to content

Commit a7ca1c4

Browse files
committed
feature: oauth login
1 parent 0913601 commit a7ca1c4

File tree

13 files changed

+1495
-123
lines changed

13 files changed

+1495
-123
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
## Connect to Claude Desktop

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: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,27 @@ This document provides common usage patterns and examples for the Galaxy MCP ser
1616
Let me get some basic information about your server to make sure everything is working properly."
1717
*Uses `get_server_info()` to retrieve server details*
1818

19+
For stdio deployments you can authenticate with a long-lived API key:
20+
21+
```python
22+
# Set GALAXY_URL and GALAXY_API_KEY in your environment or .env file
23+
connect()
24+
25+
# Or provide credentials directly
26+
connect(url="https://your-galaxy-instance.org", api_key="your-api-key")
27+
```
28+
29+
For HTTP deployments that use OAuth the active session is resolved automatically. Calling
30+
`connect()` without arguments simply confirms the session and returns user details:
31+
32+
```python
33+
session_info = connect()
34+
assert session_info["auth"] == "oauth"
35+
print(session_info["user"]["username"])
36+
```
37+
38+
#### Get server information
39+
1940
"Perfect! Your Galaxy server is running version 23.1 and has the following features available:
2041
- User registration: Enabled
2142
- File upload via FTP: Available at ftp.galaxy.org

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)