Skip to content

Feature/oauth 2.1 support #10

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 21 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
26c7bea
Add OAuth 2.1 Authentication with Scope-Based Access Control
westonbrown May 20, 2025
5aee97b
Add OAuth 2.1 infrastructure and UI components
westonbrown May 20, 2025
accf788
Refined logout logic;
westonbrown May 21, 2025
9750e8b
Cleaned up Dockerfile and entrypoint regressions
westonbrown May 22, 2025
567503f
Improved JWT validation and secret key validation logic;
westonbrown May 22, 2025
0d59cb4
Refined DockerFile; Removed unnecessary dev testing improts;
westonbrown May 22, 2025
5522072
Removed hardcodings of Nginx reverse proxy configuration
westonbrown May 23, 2025
b20d906
Merge main branch into feature/oauth-2.1-support, resolving conflicts…
aarora79 May 24, 2025
58cfebe
delete unused file
aarora79 May 24, 2025
b33e829
still trying to get service enable disable to work
aarora79 May 25, 2025
50582b0
restore entrypoint
aarora79 May 25, 2025
0bb10d1
fix nginx config generation
dheerajoruganty May 25, 2025
19c7e6e
fix: fix page redirect to /login
dheerajoruganty May 25, 2025
69a3809
fix: optimize logout page load time
dheerajoruganty May 25, 2025
d40af94
Fix SSE transport by routing MCP clients through nginx proxy to resol…
westonbrown May 26, 2025
7535044
fixed the https section not updating issue in the nginx config
aarora79 May 26, 2025
1198a5c
simplify dockerfile, add agents test suite, nginx can now take a host…
aarora79 May 26, 2025
9bcc350
simplify dockerfile, add agents test suite, nginx can now take a host…
aarora79 May 26, 2025
b6bce63
trying to get cognito working
aarora79 May 27, 2025
927bb65
Fixed the the Cognito OAuth authorization URL bug that was incorrect…
westonbrown May 28, 2025
e5046a2
wokring cognito code
aarora79 May 31, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .env.docker.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Admin credentials
ADMIN_USER=admin
ADMIN_PASSWORD=your_secure_password_here

# API Keys
POLYGON_API_KEY=your_polygon_api_key_here

# AWS Configuration
AWS_REGION=us-east-1

# OAuth Configuration
MCP_AUTH_ENABLED=true
MCP_AUTH_PROVIDER_TYPE=cognito
MCP_AUTH_BASE_URL=https://mcpgateway.ddns.net

# Cognito Configuration
MCP_AUTH_COGNITO_USER_POOL_ID=your_user_pool_id_here
MCP_AUTH_COGNITO_CLIENT_ID=your_client_id_here
MCP_AUTH_COGNITO_CLIENT_SECRET=your_client_secret_here
MCP_AUTH_COGNITO_CALLBACK_URI=${MCP_AUTH_BASE_URL}/oauth/callback/cognito
MCP_AUTH_COGNITO_REGION=us-east-1
MCP_AUTH_COGNITO_CUSTOM_DOMAIN=your_custom_domain_here

# Secret Key (will be auto-generated if not provided)
# SECRET_KEY=your_secret_key_here
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -182,3 +182,5 @@ cookies.txt
registry/server_state.json
registry/nginx_mcp_revproxy.conf
logs/
agents/test_results/
.env.docker
6 changes: 5 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ COPY . /app/
# Note: We copy it here so it's part of the image layer
COPY docker/nginx_rev_proxy.conf /app/docker/nginx_rev_proxy.conf


# Make the entrypoint script executable
COPY docker/entrypoint.sh /app/docker/entrypoint.sh
RUN chmod +x /app/docker/entrypoint.sh
Expand All @@ -42,11 +41,16 @@ ARG SECRET_KEY=""
ARG ADMIN_USER="admin"
ARG ADMIN_PASSWORD=""
ARG POLYGON_API_KEY=""
ARG MCP_AUTH_ENABLED="false"
ARG MCP_GATEWAY_DEV_MODE="true"

# Pass build args to runtime environment
ENV SECRET_KEY=$SECRET_KEY
ENV ADMIN_USER=$ADMIN_USER
ENV ADMIN_PASSWORD=$ADMIN_PASSWORD
ENV POLYGON_API_KEY=$POLYGON_API_KEY
ENV MCP_AUTH_ENABLED=$MCP_AUTH_ENABLED
ENV MCP_GATEWAY_DEV_MODE=$MCP_GATEWAY_DEV_MODE

# Run the entrypoint script when the container launches
ENTRYPOINT ["/app/docker/entrypoint.sh"]
115 changes: 110 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,14 @@ flowchart TB
* **Unified access to a governed list of MCP servers:** Access multiple MCP servers through a common MCP gateway, enabling AI Agents to dynamically discover and execute MCP tools.
* **Service Registration:** Register MCP services via JSON files or the web UI/API.
* **Web UI:** Manage services, view status, and monitor health through a web interface.
* **Authentication:** Secure login system for the web UI and API access.
* **OAuth 2.1 Authentication:**
* Standards-compliant OAuth 2.1 authorization code flow with PKCE
* Support for multiple identity providers (AWS Cognito, Okta, and others)
* Fine-grained scope-based access control
* Secure session management with proper token handling
* **MCP Protocol Support:**
* Server-Sent Events (SSE) transport via `/api/execute/{service}` endpoint
* StreamableHTTP transport via `/api/streamable/{service}` endpoint
* **Health Checks:**
* Periodic background checks for enabled services (checks `/sse` endpoint).
* Manual refresh trigger via UI button or API endpoint.
Expand Down Expand Up @@ -175,12 +182,14 @@ The Gateway and the Registry are available as a Docker container. The package in
export ADMIN_USER=admin
export ADMIN_PASSWORD=your-admin-password
export POLYGON_API_KEY=your-polygon-api-key
export GATEWAY_HOSTNAME=your-ec2-hostname
# stop any previous instance
docker stop mcp-gateway-container && docker rm mcp-gateway-container
docker run -p 80:80 -p 443:443 -p 7860:7860 \
-e ADMIN_USER=$ADMIN_USER \
-e ADMIN_PASSWORD=$ADMIN_PASSWORD \
-e POLYGON_API_KEY=$POLYGON_API_KEY \
-e GATEWAY_HOSTNAME=$GATEWAY_HOSTNAME \
-e SECRET_KEY=$(python3 -c 'import secrets; print(secrets.token_hex(32))') \
-v /var/log/mcp-gateway:/app/logs \
-v /opt/mcp-gateway/servers:/app/registry/servers \
Expand Down Expand Up @@ -224,6 +233,19 @@ The Gateway and the Registry are available as a Docker container. The package in
1. **View MCP server metadata:**
Metadata about all MCP servers connected to the Registry is available in `/opt/mcp-gateway/servers` directory. The metadata includes information gathered from `ListTools` as well as information provided while registering the server.

1. **Test the Gateway and Registry with the sample Agent and test suite**
The repo includes a test agent that can connect to the Registry to discover tools and invoke them to do interesting tasks. This functionality can be invoked either standalone or as part of a test suite.

```{.python}
python agents\agent.py --mcp-registry-url http://localhost/mcpgw/sse --message "what is the current time in clarksburg, md"
```

You can also run the full test suite and get a handy agent evaluation report. This test suite exercises the Registry functionality as well as tests the multiple built-in MCP servers provided by the Gateway.
```{python}
python agents/test_suite.py
```
The result of the tests suites are available in the `agents/test_results` folder. It contains an `accuracy.json`, a `summary.json`, a `logs` folder and a `raw_data` folder that contains the verbose output from the agent. The test suite uses an LLM as a judge to evaluate the results for accuracy and tool usage quality.

#### Running the Gateway over HTTPS

1. Enable access to TCP port 443 from the IP address of your MCP client (your laptop, or anywhere) in the inbound rules in the security group associated with your EC2 instance.
Expand All @@ -239,6 +261,7 @@ The Gateway and the Registry are available as a Docker container. The package in
-e ADMIN_USER=$ADMIN_USER \
-e ADMIN_PASSWORD=$ADMIN_PASSWORD \
-e POLYGON_API_KEY=$POLYGON_API_KEY \
-e GATEWAY_HOSTNAME=$GATEWAY_HOSTNAME \
-e SECRET_KEY=$(python3 -c 'import secrets; print(secrets.token_hex(32))') \
-v /path/to/certs:/etc/ssl/certs \
-v /path/to/private:/etc/ssl/private \
Expand Down Expand Up @@ -331,14 +354,96 @@ See the full API spec [here](docs/registry_api.md).

*(Authentication via session cookie is required for most non-login routes)*

## OAuth 2.1 Authentication

MCP Gateway now supports OAuth 2.1 authentication for secure access to the gateway and its services.

```mermaid
sequenceDiagram
participant Client as MCP Client
participant Gateway as MCP Gateway
participant IdP as Identity Provider
participant Server as MCP Server

Client->>Gateway: 1. Request tool execution
Gateway->>Gateway: 2. Check authentication
alt Not authenticated
Gateway->>Client: 3. Redirect to /oauth/login
Client->>Gateway: 4. Request /oauth/login
Gateway->>IdP: 5. Redirect to IdP with PKCE
Client->>IdP: 6. User authentication
IdP->>Gateway: 7. Authorization code
Gateway->>IdP: 8. Exchange code for tokens
Gateway->>Gateway: 9. Validate tokens, extract scopes
Gateway->>Client: 10. Set session cookie
end
Client->>Gateway: 11. Request with auth cookie
Gateway->>Gateway: 12. Verify scopes
alt Authorized
Gateway->>Server: 13. Proxy to MCP Server
Server->>Gateway: 14. Server response
Gateway->>Client: 15. Return response
else Not authorized
Gateway->>Client: Return 403 Forbidden
end
```

### Key Features

- Standards-compliant OAuth 2.1 authorization code flow with PKCE
- Multiple identity provider support (AWS Cognito, Okta, and others)
- Fine-grained scope-based access control
- Support for both SSE and StreamableHTTP transport protocols
- Configurable through environment variables or config files

### Setting up OAuth Authentication

To enable OAuth 2.1 authentication:

1. **Configure Environment Variables:**
- Set `MCP_AUTH_ENABLED=true`
- Generate a secure `SECRET_KEY`
- Configure provider-specific settings

2. **Docker Run Command Example:**

```bash
docker run -p 80:80 -p 443:443 -p 7860:7860 \
-e ADMIN_USER=$ADMIN_USER \
-e ADMIN_PASSWORD=$ADMIN_PASSWORD \
-e POLYGON_API_KEY=$POLYGON_API_KEY \
-e SECRET_KEY=$(python3 -c 'import secrets; print(secrets.token_hex(32))') \
-e MCP_AUTH_ENABLED=true \
-e MCP_AUTH_PROVIDER_TYPE=$PROVIDER_TYPE \
# Add your provider-specific environment variables here
-v /var/log/mcp-gateway:/app/logs \
-v /opt/mcp-gateway/servers:/app/registry/servers \
--name mcp-gateway-container mcp-gateway
```

See the [OAuth Documentation](docs/oauth.md) for detailed configuration options for AWS Cognito, Okta, and other providers.

### Transport Protocol Support

MCP Gateway supports both transport protocols defined in the MCP specification:

- **Server-Sent Events (SSE)**: Access via `/api/execute/{service}` endpoint
- **StreamableHTTP**: Access via `/api/streamable/{service}` endpoint

### For More Information

For comprehensive documentation on OAuth setup, transport protocols, scope-based access control, and more, see:

- [OAuth Documentation](docs/oauth.md)
- [API Documentation](docs/registry_api.md)

## Roadmap

1. Store the server information in persistent storage.
1. Add OAUTH 2.1 support to Gateway and Registry.
1. Use GitHub API to retrieve information (license, programming language etc.) about MCP servers.
1. Add option to deploy MCP servers.
2. Use GitHub API to retrieve information (license, programming language etc.) about MCP servers.
3. Add option to deploy MCP servers.

## License

- Free for non-commercial use under AGPL-3.0
- Commercial use requires a paid license
- Commercial use requires a paid license
2 changes: 1 addition & 1 deletion agents/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ async def invoke_mcp_tool(mcp_registry_url: str, server_name: str, tool_name: st

How to use intelligent_tool_finder:
1. When you identify that a task requires a specialized tool (e.g., image generation, specialized API access, etc.)
2. Call the tool with a description of what you need: `intelligent_tool_finder("description of needed capability")`, Use admin/password for authentication.
2. Call the tool with a description of what you need: `intelligent_tool_finder("description of needed capability")`
3. The tool will return the most appropriate specialized tool along with usage instructions
4. You can then use the invoke_mcp_tool to invoke this discovered tool by providing the MCP Registry URL, server name, tool name, and required arguments

Expand Down
Loading