Skip to content
This repository was archived by the owner on Oct 17, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: Lint

on: [push, pull_request]
on: [pull_request]

permissions:
contents: read # Required to check out the code
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -173,3 +173,7 @@ cython_debug/
# PyPI configuration file
.pypirc
cookies.txt

# MCP Gateway specific
registry/server_state.json
registry/nginx_mcp_revproxy.conf
194 changes: 119 additions & 75 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
<img src="registry/static/mcp_gateway_horizontal_white_logo.png" alt="MCP Gateway Logo" width="100%">

# ⚠️ ACTIVE DEVELOPMENT - WORK IN PROGRESS ⚠️

> **WARNING**: This repository is under active development. Expect frequent updates and breaking changes as we improve functionality and refine APIs. We recommend pinning to specific versions for production use. Star the repository to track our progress!
Expand All @@ -7,114 +9,156 @@

# MCP Gateway Registry

This application provides a web interface and API for registering and managing backend services that can be proxied through a gateway (like Nginx). It allows viewing service status, descriptions, and toggling their availability (currently simulated).
This application provides a web interface and API for registering and managing backend MCP (Meta-Computation Protocol) services. It acts as a central registry, health monitor, and dynamic reverse proxy configuration generator for Nginx.

## Features

* **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.
* **Health Checks:**
* Periodic background checks for enabled services (checks `/sse` endpoint).
* Manual refresh trigger via UI button or API endpoint.
* **Real-time UI Updates:** Uses WebSockets to push health status, tool counts, and last-checked times to all connected clients.
* **Dynamic Nginx Configuration:** Generates an Nginx reverse proxy configuration file (`registry/nginx_mcp_revproxy.conf`) based on registered services and their enabled/disabled state.
* **MCP Tool Discovery:** Automatically fetches and displays the list of tools (name, description, schema) for healthy services using the MCP client library.
* **Service Management:**
* Enable/Disable services directly from the UI.
* Edit service details (name, description, URL, tags, etc.).
* **Filtering & Statistics:** Filter the service list in the UI (All, Enabled, Disabled, Issues) and view basic statistics.
* **UI Customization:**
* Dark/Light theme toggle (persisted in local storage).
* Collapsible sidebar (state persisted in local storage).
* **State Persistence:** Enabled/Disabled state is saved to `registry/server_state.json` (and ignored by Git).

## Prerequisites

* Python 3.12+
* [uv](https://github.com/astral-sh/uv) (or `pip`) for package management.
* Python 3.11+ (or compatible version supporting FastAPI and MCP Client)
* [uv](https://github.com/astral-sh/uv) (recommended) or `pip` for package management.
* Nginx (or another reverse proxy) installed and configured to use the generated configuration file.

## Installation

1. **Clone the repository (if you haven't already):**
1. **Clone the repository:**
```bash
git clone <your-repo-url>
cd mcp-gateway
```

2. **Create and activate a virtual environment (recommended):**
Using `venv` (standard Python):
```bash
python -m venv .venv
source .venv/bin/activate # On Windows use `.venv\Scripts\activate`
```
Using `uv` (which handles environments automatically):
You can skip explicit environment creation if you use `uv run`.

3. **Install dependencies:** Dependencies are defined in `pyproject.toml`.

Using `uv`:
```bash
# Installs dependencies defined in pyproject.toml
uv pip install .
```
Using `pip`:
```bash
# Installs dependencies defined in pyproject.toml
pip install .
```
* Using `venv`:
```bash
python -m venv .venv
source .venv/bin/activate # Linux/macOS
# .venv\Scripts\activate # Windows
```
* `uv` handles environments automatically via `uv run` or `uv pip sync`.

3. **Install dependencies:** (Defined in `pyproject.toml` and locked in `uv.lock`)
* Using `uv`:
```bash
uv pip sync
```
* Using `pip`:
```bash
pip install .
```

## Configuration

1. **Environment Variables:** The application uses a `.env` file in the project root (`mcp-gateway/`) for configuration. Create this file if it doesn't exist:
1. **Environment Variables:** Create a `.env` file in the project root (`mcp-gateway/`).
```bash
cp .env.example .env # If you create an example file
# Or create it manually
touch .env
```

2. **Edit `.env`:** Add the following variables:
Add the following variables, replacing placeholders with secure values:
```dotenv
# A strong, randomly generated secret key for session security
SECRET_KEY='your_strong_random_secret_key'
# REQUIRED: A strong, randomly generated secret key for session security
SECRET_KEY='your_strong_random_secret_key_32_chars_or_more'

# Credentials for the web interface login
# REQUIRED: Credentials for the web interface login
ADMIN_USER='admin'
ADMIN_PASSWORD='your_secure_password'
```
*Replace the placeholder values with secure ones.*

3. **Service Definitions:** Services are defined by JSON files in the `registry/servers/` directory. See existing files for the expected format. The application loads these on startup.
**⚠️ IMPORTANT:** Use a strong, unpredictable `SECRET_KEY` for production environments.

2. **Service Definitions:** Services can be added via the UI after starting the application. Alternatively, you can manually create JSON files in the `registry/servers/` directory before the first run. Each file defines one service. Example (`my_service.json`):
```json
{
"server_name": "My Example Service",
"description": "Provides example functionality.",
"path": "/my-service",
"proxy_pass_url": "http://localhost:8001",
"tags": ["example", "test"],
"num_tools": 0,
"num_stars": 0,
"is_python": true,
"license": "MIT",
"tool_list": []
}
```

## Running the Application

**Using `uv run`:**

This command leverages `uv` to manage the environment and run the development server.

```bash
uv run uvicorn registry.main:app --reload --host 0.0.0.0 --port 7860
```
* `--reload`: Enables auto-reload on code changes.
* `--host 0.0.0.0`: Makes the server accessible on your network.
* `--port 7860`: Specifies the port to run on.

**Using `uvicorn` directly (after installing dependencies and activating venv):**

```bash
uvicorn registry.main:app --reload --host 0.0.0.0 --port 7860
```

Once running, you can access the web interface at `http://<your-server-ip>:7860`.
1. **Start the FastAPI server:**
* Using `uv`:
```bash
uv run uvicorn registry.main:app --reload --host 0.0.0.0 --port 7860
```
* Using `uvicorn` directly (ensure virtual environment is active):
```bash
uvicorn registry.main:app --reload --host 0.0.0.0 --port 7860
```
* `--reload`: Enables auto-reload for development. Remove for production.
* `--host 0.0.0.0`: Makes the server accessible on your network.
* `--port 7860`: Specifies the port.

2. **Configure Nginx:**
* The application generates `registry/nginx_mcp_revproxy.conf` on startup.
* Ensure your Nginx instance is running and includes this configuration file in its main `nginx.conf` (e.g., using an `include` directive in the `http` block).
* Reload or restart Nginx to apply the configuration (`sudo nginx -s reload`).
* **Note:** Detailed Nginx setup is beyond the scope of this README. The generated file assumes Nginx is listening on a standard port (e.g., 80 or 443) and proxies requests starting with registered paths (e.g., `/my-service`) to the appropriate backend defined by `proxy_pass_url`.

3. **Access the UI:** Open your web browser and navigate to the address where Nginx is serving the application (e.g., `http://<your-nginx-server-ip>`). You should be redirected to the login page at `/login` (served by the FastAPI app). *Direct access via port 7860 is primarily for the UI itself; service proxying relies on Nginx.*

## Usage

1. **Login:** Use the `ADMIN_USER` and `ADMIN_PASSWORD` from your `.env` file.
2. **Register Service:** Use the "Register New Service" form in the UI (or the API).
3. **Manage Services:**
* Toggle the Enabled/Disabled switch. The Nginx config automatically comments/uncomments the relevant `location` block.
* Click "Modify" to edit service details.
* Click the refresh icon (🔄) in the card header to manually trigger a health check and tool list update for enabled services.
4. **View Tools:** Click the tool count icon (🔧) in the card footer to open a modal displaying discovered tools and their schemas for healthy services.
5. **Filter:** Use the sidebar links to filter the displayed services.

## Project Structure

* `registry/`: Contains the main FastAPI application (`main.py`).
* `registry/`: Main FastAPI application (`main.py`).
* `servers/`: Stores JSON definitions for each registered service.
* `static/`: Static assets (CSS, JS, images).
* `templates/`: Jinja2 HTML templates.
* `.env`: Configuration file (needs to be created).
* `templates/`: Jinja2 HTML templates (`index.html`, `login.html`, etc.).
* `server_state.json`: Stores the enabled/disabled state (created automatically, **ignored by Git**).
* `nginx_mcp_revproxy.conf`: Nginx config generated dynamically (**ignored by Git**).
* `nginx_template.conf`: Template used for Nginx config generation.
* `.env`: Environment variables (local configuration, **ignored by Git**).
* `.gitignore`: Specifies files ignored by Git.
* `pyproject.toml`: Project metadata and dependencies.
* `uv.lock`: Locked dependency versions (used by `uv`).
* `README.md`: This file.
* `LICENSE`: Project license file.

## API Endpoints (Brief Overview)

* `POST /register`: Register a new service (form data).
* `POST /toggle/{service_path}`: Enable/disable a service (form data).
* `POST /edit/{service_path}`: Update service details (form data).
* `GET /api/server_details/{service_path}`: Get full details for a service (JSON).
* `GET /api/tools/{service_path}`: Get the discovered tool list for a service (JSON).
* `POST /api/refresh/{service_path}`: Manually trigger a health check/tool update.
* `GET /login`, `POST /login`, `POST /logout`: Authentication routes.
* `WS /ws/health_status`: WebSocket endpoint for real-time updates.

## Registering New Services (API)

You can register new services programmatically by sending a POST request to the `/register` endpoint.

* **URL:** `/register`
* **Method:** `POST`
* **Authentication:** Requires a valid session cookie obtained via login.
* **Content-Type:** `application/x-www-form-urlencoded`
* **Form Data:**
* `name`: (String) Display name of the service.
* `description`: (String) Description of the service.
* `path`: (String) URL path for the service (e.g., `/my-service`).
* `tags`: (String, Optional) Comma-separated list of tags.
* `num_tools`: (Integer, Optional, Default: 0) Number of tools.
* `num_stars`: (Integer, Optional, Default: 0) Number of stars.
* `is_python`: (Boolean, Optional, Default: false) Whether it's a Python service.
* `license`: (String, Optional, Default: "N/A") License information.

**Example using `curl` (after logging in via the browser to get a cookie):**
*(Authentication via session cookie is required for most non-login routes)*

```bash
curl -X POST http://localhost:7860/register \
Expand Down
Loading
Loading