# Create Plant
Source: https://docs.unla.amoylab.com/en/api-reference/endpoint/create
POST /plants
Creates a new plant in the store
# Delete Plant
Source: https://docs.unla.amoylab.com/en/api-reference/endpoint/delete
DELETE /plants/{id}
Deletes a single plant based on the ID supplied
# Get Plants
Source: https://docs.unla.amoylab.com/en/api-reference/endpoint/get
GET /plants
Returns all plants from the system that the user has access to
# New Plant
Source: https://docs.unla.amoylab.com/en/api-reference/endpoint/webhook
WEBHOOK /plant/webhook
Information about a new plant added to the store
# Introduction
Source: https://docs.unla.amoylab.com/en/api-reference/introduction
Example section for showcasing API endpoints
If you're not looking to build API reference documentation, you can delete
this section by removing the api-reference folder.
## Welcome
There are two ways to build API documentation: [OpenAPI](https://mintlify.com/docs/api-playground/openapi/setup) and [MDX components](https://mintlify.com/docs/api-playground/mdx/configuration). For the starter kit, we are using the following OpenAPI specification.
View the OpenAPI specification file
## Authentication
All API endpoints are authenticated using Bearer tokens and picked up from the specification file.
```json theme={null}
"security": [
{
"bearerAuth": []
}
]
```
# Cherry Studio Configuration Guide
Source: https://docs.unla.amoylab.com/en/client-usage/cherry-studio
How to configure MCP Gateway in Cherry Studio
Cherry Studio is another AI client tool that supports MCP (Model Context Protocol). This document describes how to configure MCP Gateway in Cherry Studio.
## Configuration Steps
Launch the Cherry Studio application
Find settings or configuration options in Cherry Studio
Add MCP Gateway connection information:
* **Server URL**: `http://localhost:5235/gateway/user/sse`
* **Protocol**: SSE (Server-Sent Events)
Save configuration and test if the connection is successful
## Supported Endpoints
Cherry Studio supports the following MCP Gateway endpoints:
* **SSE**: `http://localhost:5235/gateway/user/sse`
* **Streamable HTTP**: `http://localhost:5235/gateway/user/mcp`
* **Message**: `http://localhost:5235/gateway/user/message`
## Usage Example
After configuration is complete, you can do the following in Cherry Studio:
1. **View Available Tools**: The interface will display the tool list retrieved from MCP Gateway
2. **Execute Operations**: Communicate with AI through natural language and let AI call corresponding tools
3. **View Results**: Observe the results of tool execution and returned data
## Features
Cherry Studio can understand your needs and automatically select appropriate tools to execute operations
Save conversation history and tool execution records for easy review and repeated operations
Support configuring multiple MCP Servers to manage different business scenarios
## Common Issues
* Ensure MCP Gateway service is running
* Check network connection and port access permissions
* Verify URL configuration format is correct
* Check if MCP Server configuration is correct
* Check Cherry Studio's error logs
* Verify MCP Gateway's tool configuration
* Reasonably configure tool timeout settings
* Avoid frequent long-duration operations
* Consider using batch operations to reduce call frequency
## Advanced Configuration
### Multi-Service Configuration
If you have multiple business services, you can configure multiple MCP connections in Cherry Studio:
```
User Service: http://localhost:5235/gateway/user/sse
Order Service: http://localhost:5235/gateway/order/sse
Product Service: http://localhost:5235/gateway/product/sse
```
### Authentication Configuration
For services that require authentication, ensure necessary authentication information is included in request headers:
* Bearer Token
* API Key
* Custom Headers
For specific authentication configuration methods, please refer to Cherry Studio's official documentation or contact Cherry Studio's technical support.
## More Resources
Visit Cherry Studio's official website for more information and help
# Cursor Configuration Guide
Source: https://docs.unla.amoylab.com/en/client-usage/cursor
How to configure MCP Gateway in Cursor
For more detailed Cursor MCP configuration tutorials, please check the [official Cursor documentation](https://docs.cursor.com/context/model-context-protocol)
## Configuration Steps
Here's a simple demonstration of the most basic configuration method. Make sure you have created the relevant directories and files:
```bash theme={null}
mkdir -p .cursor
touch .cursor/mcp.json
```
Add the following configuration to `.cursor/mcp.json`. Here we'll use our own mock user service for testing:
```json theme={null}
{
"mcpServers": {
"user": {
"url": "http://localhost:5235/gateway/user/sse"
}
}
}
```
1. Open Cursor settings
2. Enable this MCP Server in the **MCP** section
3. After enabling, you'll see it become a small green dot
4. It will also list the available Tools
## Configuration Verification
After configuration is complete, you can see the following in Cursor's settings interface:
Green dot indicates MCP Server connection is normal
The interface will display the list of available tools retrieved from MCP Gateway
## Usage Example
Finally, you can try it in the Chat window, for example, ask it to help you register a user, then query that user's information. If it works, you're all set.
### Example Conversation
```
Help me register a user Leo ifuryst@gmail.com
```
```
Help me query user ifuryst@gmail.com, if not found please register with username Leo
```
Through actual testing, we found that this mock service may cause model errors in some cases due to involving names and emails, resulting in inability to call. You can ignore this situation and configure actual APIs for use.
## Common Issues
* Ensure MCP Gateway service is running
* Check if port 5235 is accessible
* Verify URL configuration is correct
* Check if MCP Server configuration is loaded correctly
* Verify tool permission configuration
* Check MCP Gateway logs for detailed error information
* Restart Cursor
* Reload MCP configuration
* Check if configuration file format is correct
## Advanced Configuration
For more complex use cases, you can configure multiple MCP Servers:
```json theme={null}
{
"mcpServers": {
"user-service": {
"url": "http://localhost:5235/gateway/user/sse"
},
"order-service": {
"url": "http://localhost:5235/gateway/order/sse"
},
"product-service": {
"url": "http://localhost:5235/gateway/product/sse"
}
}
}
```
Each MCP Server corresponds to a business domain, which allows better organization and management of different functional modules.
# API Server Configuration
Source: https://docs.unla.amoylab.com/en/configuration/apiserver
Detailed explanation of apiserver.yaml configuration file
The configuration file supports environment variable injection using the `${VAR:default}` syntax. If an environment variable is not set, the default value will be used.
A common practice is to inject values through different `.env`, `.env.development`, `.env.prod` files, though you can also directly modify the configuration with hardcoded values.
## Logging Configuration
Logging configuration controls the application's log output behavior:
```yaml theme={null}
logger:
level: "${APISERVER_LOGGER_LEVEL:info}" # Log level: debug, info, warn, error
format: "${APISERVER_LOGGER_FORMAT:console}" # Log format: json, console
output: "${APISERVER_LOGGER_OUTPUT:stdout}" # Output method: stdout, file
file_path: "${APISERVER_LOGGER_FILE_PATH:/var/log/unla/apiserver.log}" # Log file path (when output is file)
max_size: ${APISERVER_LOGGER_MAX_SIZE:100} # Maximum log file size (MB)
max_backups: ${APISERVER_LOGGER_MAX_BACKUPS:3} # Number of backup files to retain
max_age: ${APISERVER_LOGGER_MAX_AGE:7} # Backup file retention days
compress: ${APISERVER_LOGGER_COMPRESS:true} # Whether to compress backup files
color: ${APISERVER_LOGGER_COLOR:true} # Whether to use colors in console output
stacktrace: ${APISERVER_LOGGER_STACKTRACE:true} # Whether error logs include stack traces
```
Supports four levels: debug, info, warn, error
Supports JSON structured output and console readable format
Automatically manages log file size and quantity
Error logs can include detailed call stack information
## Internationalization Configuration
Internationalization configuration is used to support multi-language interfaces:
```yaml theme={null}
i18n:
path: "${APISERVER_I18N_PATH:/etc/unla/i18n}" # Translation file path
```
The translation file path should contain translation files for various languages to support multi-language user interfaces.
## Chat Message Database Configuration
This configuration mainly targets the backend chat message storage configuration (of course, this can be stored in the same database as the proxy configuration), primarily used to store chat sessions and message data from the Web interface.
The chat message database is mainly used to store MCP chat records conducted through the Web interface, and is separate from the gateway proxy configuration storage.
### Supported Databases
Currently supports 3 types of databases:
Suitable for development environments and small-scale deployments
Recommended for production environments
Traditional relational database choice
### Configuration Example
```yaml theme={null}
database:
type: "${APISERVER_DB_TYPE:sqlite}" # Database type (sqlite, postgres, mysql)
host: "${APISERVER_DB_HOST:localhost}" # Database host address
port: ${APISERVER_DB_PORT:5432} # Database port
user: "${APISERVER_DB_USER:postgres}" # Database username
password: "${APISERVER_DB_PASSWORD:example}" # Database password
dbname: "${APISERVER_DB_NAME:./unla.db}" # Database name or file path
sslmode: "${APISERVER_DB_SSL_MODE:disable}" # SSL mode for database connection
```
If you need additional database support, you can request it in the [Issues](https://github.com/amoylab/unla/issues), or you can directly implement the corresponding impl and submit a PR :)
## Gateway Proxy Storage Configuration
This is used to store gateway proxy configurations, which corresponds to the configuration that maps from MCP to API.
Currently supports 2 storage methods:
Store in database, with each configuration as a record. Currently supports three databases: SQLite3, PostgreSQL, MySQL
Store configurations through API endpoints, allowing for external configuration management systems
The `revision_history_limit` parameter controls the number of configuration version histories retained by the system, which helps with configuration rollback and auditing. The default is to retain 10 versions.
### Configuration Example
```yaml theme={null}
storage:
type: "${GATEWAY_STORAGE_TYPE:db}" # Storage type: db, api
revision_history_limit: ${GATEWAY_STORAGE_REVISION_HISTORY_LIMIT:10} # Number of version histories to retain
# Database configuration (used when type is 'db')
database:
type: "${GATEWAY_DB_TYPE:sqlite}" # Database type (sqlite, postgres, mysql)
host: "${GATEWAY_DB_HOST:localhost}" # Database host address
port: ${GATEWAY_DB_PORT:5432} # Database port
user: "${GATEWAY_DB_USER:postgres}" # Database username
password: "${GATEWAY_DB_PASSWORD:example}" # Database password
dbname: "${GATEWAY_DB_NAME:./unla.db}" # Database name or file path
sslmode: "${GATEWAY_DB_SSL_MODE:disable}" # SSL mode for database connection
# API configuration (used when type is 'api')
api:
url: "${GATEWAY_STORAGE_API_URL:}" # API endpoint URL
configJSONPath: "${GATEWAY_STORAGE_API_CONFIG_JSON_PATH:}" # JSON path for config in API response
timeout: "${GATEWAY_STORAGE_API_TIMEOUT:30s}" # Request timeout
```
## Notification Configuration
The notification configuration module is mainly used to let `mcp-gateway` sense updates and perform hot reloading without restarting the service when configuration is updated.
### Supported Notification Methods
Notify by sending operating system signals, similar to `kill -SIGHUP ` or `nginx -s reload`
Notify by calling an API, `mcp-gateway` will listen on a separate port
Notify through Redis publish/subscribe functionality, suitable for single-machine or cluster deployments
Composite notification using multiple methods, `signal` and `api` are always enabled by default
### Notification Roles
Sender, responsible for sending notifications, `apiserver` can only use this mode
Receiver, responsible for receiving notifications, single-machine `mcp-gateway` should only use this mode
Both sender and receiver, cluster-deployed `mcp-gateway` can use this method
### Configuration Example
```yaml theme={null}
notifier:
role: "${APISERVER_NOTIFIER_ROLE:sender}" # Role: 'sender' or 'receiver'
type: "${APISERVER_NOTIFIER_TYPE:signal}" # Type: 'signal', 'api', 'redis' or 'composite'
# Signal configuration (used when type is 'signal')
signal:
signal: "${APISERVER_NOTIFIER_SIGNAL:SIGHUP}" # Signal to send
pid: "${APISERVER_NOTIFIER_SIGNAL_PID:/var/run/mcp-gateway.pid}" # PID file path
# API configuration (used when type is 'api')
api:
port: ${APISERVER_NOTIFIER_API_PORT:5235} # API port
target_url: "${APISERVER_NOTIFIER_API_TARGET_URL:http://localhost:5235/_reload}" # Reload endpoint
# Redis configuration (used when type is 'redis')
redis:
addr: "${APISERVER_NOTIFIER_REDIS_ADDR:localhost:6379}" # Redis address
password: "${APISERVER_NOTIFIER_REDIS_PASSWORD:UseStrongPasswordIsAGoodPractice}" # Redis password
db: ${APISERVER_NOTIFIER_REDIS_DB:0} # Redis database number
topic: "${APISERVER_NOTIFIER_REDIS_TOPIC:mcp-gateway:reload}" # Redis publish/subscribe topic
```
## Super Administrator Configuration
Super administrator configuration is used to set up the system's initial administrator account. Each time `apiserver` starts, it will automatically detect if it exists, and if not, it will be created automatically.
```yaml theme={null}
super_admin:
username: "${SUPER_ADMIN_USERNAME:admin}" # Super administrator username
password: "${SUPER_ADMIN_PASSWORD:changeme-please-use-a-secure-password}" # Super administrator password (please change in production)
```
**Strongly recommend using strong passwords in production or public network environments!**
## JWT Configuration
JWT configuration is used to set web authentication related parameters:
```yaml theme={null}
jwt:
secret_key: "${APISERVER_JWT_SECRET_KEY:changeme-please-generate-a-random-secret}" # JWT secret key (please change in production)
duration: "${APISERVER_JWT_DURATION:24h}" # Token validity period
```
**Strongly recommend using strong passwords in production or public network environments!**
## OAuth Login Configuration
OAuth configuration enables third-party login functionality, currently supporting `Google` and `GitHub` login. When the corresponding `client_id` and `client_secret` are configured, the web interface will automatically enable OAuth login options.
```yaml theme={null}
oauth:
# Google OAuth Configuration
google:
client_id: "${OAUTH_GOOGLE_CLIENT_ID:}" # Google OAuth Client ID
client_secret: "${OAUTH_GOOGLE_CLIENT_SECRET:}" # Google OAuth Client Secret
# GitHub OAuth Configuration
github:
client_id: "${OAUTH_GITHUB_CLIENT_ID:}" # GitHub OAuth Client ID
client_secret: "${OAUTH_GITHUB_CLIENT_SECRET:}" # GitHub OAuth Client Secret
```
Supports Google account login, requires OAuth app configuration in Google Cloud Console
Supports GitHub account login, requires creating an OAuth app in GitHub
* OAuth login options are only enabled when the corresponding `client_id` and `client_secret` are configured
* OAuth login can be used alongside local account login
* Users logging in via OAuth for the first time will have accounts created automatically
## Configuration File Location
By default, the configuration file should be placed in the following locations:
* Container deployment: `/app/configs/apiserver.yaml`
* Binary deployment: `./configs/apiserver.yaml`
You can specify a custom configuration file path through environment variables or command line parameters.
# Gateway Proxy Configuration
Source: https://docs.unla.amoylab.com/en/configuration/gateways
Detailed MCP Gateway proxy service configuration guide
## HTTP Service Proxy Configuration
The following is a specific configuration example for HTTP service proxy, including routing, tools and other configurations:
```yaml theme={null}
name: "mock-server" # Proxy service name, globally unique
tenant: "default" # Tenant identifier for multi-tenant scenarios
# Routing configuration
routers:
- server: "mock-server" # Service name
prefix: "/gateway/user" # Route prefix, globally unique, non-repeatable, recommended to distinguish prefixes by service or domain+module
# CORS configuration
cors:
allowOrigins: # Development and test environments can be fully open, production should be opened as needed. (Most MCP Clients do not need to open cross-origin)
- "*"
allowMethods: # Allowed request methods, open as needed, for MCP (SSE and Streamable) usually only these 3 methods are needed
- "GET"
- "POST"
- "PUT"
- "OPTIONS"
allowHeaders:
- "Content-Type" # Must be allowed
- "Authorization" # Required for authentication needs to support carrying this key in requests
- "Mcp-Session-Id" # For MCP, must support carrying this key in requests, otherwise Streamable HTTP cannot be used normally
- "mcp-protocol-version" # MCP protocol version header for protocol version negotiation
exposeHeaders:
- "Mcp-Session-Id" # For MCP, when cross-origin is enabled, this key must be exposed, otherwise Streamable HTTP cannot be used normally
- "mcp-protocol-version" # MCP protocol version header
allowCredentials: true # Whether to add Access-Control-Allow-Credentials: true header
# Service configuration
servers:
- name: "mock-server" # Service name, must match server in routers
description: "Mock User Service" # Service description
allowedTools: # List of allowed tools (subset of tools)
- "register_user"
- "get_user_by_email"
- "update_user_preferences"
- "update_user_avatar"
config: # Service-level configuration, can be referenced in tools via {{.Config}}
Cookie: 123 # Hardcoded configuration
Authorization: 'Bearer {{ env "AUTH_TOKEN" }}' # Configuration from environment variables, usage is '{{ env "ENV_VAR_NAME" }}'
# Tool configuration
tools:
- name: "register_user" # Tool name
description: "Register a new user" # Tool description
method: "POST" # HTTP method for requesting target (upstream, backend) service
endpoint: "http://localhost:5236/users" # Target service address
headers: # Request header configuration for carrying headers when requesting target service
Content-Type: "application/json" # Hardcoded request header
Authorization: "{{.Config.Authorization}}" # Use value from service configuration
Cookie: "{{.Config.Cookie}}" # Use value from service configuration
args: # Parameter configuration
- name: "username" # Parameter name
position: "body" # Parameter position: header, query, path, body, form-data
required: true # Whether parameter is required
type: "string" # Parameter type
description: "Username" # Parameter description
default: "" # Default value
- name: "email"
position: "body"
required: true
type: "string"
description: "Email"
default: ""
requestBody: |- # Request body template for dynamically generating request body, e.g., values extracted from parameters (MCP request arguments)
{
"username": "{{.Args.username}}",
"email": "{{.Args.email}}"
}
responseBody: |- # Response body template for dynamically generating response body, e.g., values extracted from response
{
"id": "{{.Response.Data.id}}",
"username": "{{.Response.Data.username}}",
"email": "{{.Response.Data.email}}",
"createdAt": "{{.Response.Data.createdAt}}"
}
- name: "get_user_by_email"
description: "Get user by email"
method: "GET"
endpoint: "http://localhost:5236/users/email/{{.Args.email}}"
args:
- name: "email"
position: "path"
required: true
type: "string"
description: "Email"
default: ""
responseBody: |-
{
"id": "{{.Response.Data.id}}",
"username": "{{.Response.Data.username}}",
"email": "{{.Response.Data.email}}",
"createdAt": "{{.Response.Data.createdAt}}"
}
- name: "update_user_preferences"
description: "Update user preferences"
method: "PUT"
endpoint: "http://localhost:5236/users/{{.Args.email}}/preferences"
headers:
Content-Type: "application/json"
Authorization: "{{.Request.Headers.Authorization}}"
Cookie: "{{.Config.Cookie}}"
args:
- name: "email"
position: "path"
required: true
type: "string"
description: "Email"
default: ""
- name: "isPublic"
position: "body"
required: true
type: "boolean"
description: "Whether the user profile is public"
default: "false"
- name: "showEmail"
position: "body"
required: true
type: "boolean"
description: "Whether to show email in profile"
default: "true"
- name: "theme"
position: "body"
required: true
type: "string"
description: "User interface theme"
default: "light"
- name: "tags"
position: "body"
required: true
type: "array"
items:
type: "string"
enum: ["developer", "designer", "manager", "tester"]
description: "User role tags"
default: "[]"
- name: "settings"
position: "body"
required: false
type: "object"
description: "User custom settings as key-value pairs"
default: "{}"
- name: "notifications"
position: "body"
required: false
type: "array"
description: "User notification preferences"
items:
type: "object"
properties:
type:
type: "string"
description: "Notification type (email, push, sms)"
channel:
type: "string"
description: "Notification channel (marketing, system, security)"
enabled:
type: "boolean"
description: "Whether this notification is enabled"
frequency:
type: "number"
description: "Notification frequency (0: realtime, 1: daily, 2: weekly, 3: monthly)"
default: "[]"
requestBody: |-
{
"isPublic": {{.Args.isPublic}},
"showEmail": {{.Args.showEmail}},
"theme": "{{.Args.theme}}",
"tags": {{.Args.tags}},
"settings": {{ toJSON .Args.settings }},
"notifications": {{ .Args.notifications }}
}
responseBody: |-
{
"id": "{{.Response.Data.id}}",
"username": "{{.Response.Data.username}}",
"email": "{{.Response.Data.email}}",
"createdAt": "{{.Response.Data.createdAt}}",
"preferences": {
"isPublic": {{.Response.Data.preferences.isPublic}},
"showEmail": {{.Response.Data.preferences.showEmail}},
"theme": "{{.Response.Data.preferences.theme}}",
"tags": {{.Response.Data.preferences.tags}},
"settings": {{ toJSON .Response.Data.preferences.settings }},
"notifications": {{ toJSON .Response.Data.preferences.notifications }}
}
}
- name: "update_user_avatar"
description: "Update user avatar using a URL via multipart form"
method: "POST"
endpoint: "http://localhost:5236/users/{{.Args.email}}/avatar"
headers:
Authorization: "{{.Request.Headers.Authorization}}"
Cookie: "{{.Config.Cookie}}"
args:
- name: "email"
position: "path"
required: true
type: "string"
description: "Email of the user"
default: ""
- name: "url"
position: "form-data"
required: true
type: "string"
description: "The avatar image URL"
default: ""
responseBody: |-
{
"message": "{{.Response.Data.message}}",
"avatarUrl": "{{.Response.Data.avatarUrl}}"
}
```
## Configuration Explanation
### 1. Basic Configuration
MCP Gateway service listening port, default 5235
Process ID file path for process management and reloading
Configuration reload interval, default 600s
Whether to enable automatic configuration reloading
A configuration can be treated as a namespace, recommended to distinguish by service or domain. A service contains many API interfaces, each API interface corresponds to a Tool.
* `name`: Proxy service name, globally unique, used to identify different proxy services
* `tenant`: Tenant identifier for data isolation and permission management in multi-tenant scenarios
### 2. Routing Configuration
Routing configuration is used to define request forwarding rules:
```yaml theme={null}
routers:
- server: "mock-server" # Service name, must match name in servers
prefix: "/gateway/user" # Route prefix, globally unique, non-repeatable
```
Currently, by default, 3 endpoints are derived based on `prefix`:
* SSE: `${prefix}/sse`, e.g., `/gateway/user/sse`
* SSE: `${prefix}/message`, e.g., `/gateway/user/message`
* StreamableHTTP: `${prefix}/mcp`, e.g., `/gateway/user/mcp`
### 3. CORS Configuration
Cross-Origin Resource Sharing (CORS) configuration is used to control access permissions for cross-origin requests:
```yaml theme={null}
cors:
allowOrigins: # Development and test environments can be fully open, production should be opened as needed. (Most MCP Clients do not need to open cross-origin)
- "*"
allowMethods: # Allowed request methods, open as needed, for MCP (SSE and Streamable) usually only these 3 methods are needed
- "GET"
- "POST"
- "OPTIONS"
allowHeaders:
- "Content-Type" # Must be allowed
- "Authorization" # Required for authentication needs to support carrying this key in requests
- "Mcp-Session-Id" # For MCP, must support carrying this key in requests, otherwise Streamable HTTP cannot be used normally
exposeHeaders:
- "Mcp-Session-Id" # For MCP, when cross-origin is enabled, this key must be exposed, otherwise Streamable HTTP cannot be used normally
allowCredentials: true # Whether to add Access-Control-Allow-Credentials: true header
```
Usually, MCP Clients do not need to open cross-origin
### 4. Service Configuration
Service configuration is used to define service metadata, associated tool lists, and service-level configuration:
```yaml theme={null}
servers:
- name: "mock-server" # Service name, must match server in routers
namespace: "user-service" # Service namespace for service grouping
description: "Mock User Service" # Service description
allowedTools: # List of allowed tools (subset of tools)
- "register_user"
- "get_user_by_email"
- "update_user_preferences"
config: # Service-level configuration, can be referenced in tools via {{.Config}}
Cookie: 123 # Hardcoded configuration
Authorization: 'Bearer {{ env "AUTH_TOKEN" }}' # Configuration from environment variables, usage is '{{ env "ENV_VAR_NAME" }}'
```
Service-level configuration can be referenced in tools via `{{.Config}}`. This can be hardcoded in the configuration file or obtained from environment variables. For environment variable injection, reference using `{{ env "ENV_VAR_NAME" }}`.
### 5. Tool Configuration
Tool configuration is used to define specific API call rules. Each parameter can set a default value (default), which will be automatically used when the parameter is not provided in the MCP request.
#### 5.1 Request Parameter Assembly
When requesting the target service, parameter assembly is involved. Currently there are several sources:
1. `.Config`: Extract values from service-level configuration
2. `.Args`: Extract values directly from request parameters
3. `.Request`: Values extracted from the request, including request headers `.Request.Headers`, request body `.Request.Body`, etc.
Parameter position (position) supports the following types:
* `header`: Parameter will be placed in request headers
* `query`: Parameter will be placed in URL query string
* `path`: Parameter will be placed in URL path
* `body`: Parameter will be placed in JSON format request body
* `form-data`: Parameter will be placed in multipart/form-data format request body, for file upload scenarios
Parameter type (type) supports the following types:
* `string`: String type
* `number`: Number type
* `boolean`: Boolean type
* `array`: Array type, needs to be used with `items` to define array element types
* `object`: Object type, can use `properties` to define object structure
For complex `array` type parameters, detailed element structures can be defined:
```yaml theme={null}
- name: "notifications"
position: "body"
required: false
type: "array"
description: "User notification preferences"
items:
type: "object"
properties:
type:
type: "string"
description: "Notification type (email, push, sms)"
enabled:
type: "boolean"
description: "Whether this notification is enabled"
default: "[]"
```
When using `form-data` as parameter position, no need to specify `requestBody`, the system will automatically assemble parameters into multipart/form-data format.
Additionally, `header` and `query` parameters are auto-injected into the downstream request (Header key equals the parameter name; Query is appended to the URL). For example:
```yaml theme={null}
args:
- name: "username" # Sends header: Username:
position: "header"
- name: "traceId" # Appends ?traceId= to URL
position: "query"
```
Example arguments from MCP client:
```json theme={null}
{
"username": "alice",
"traceId": "t-123",
"avatarUrl": "https://img.example.com/1.png"
}
```
* `header` is auto-written to downstream headers (key = param name)
* `query` is auto-appended to the URL query string
* `form-data` is auto-assembled as multipart/form-data
Tool config snippet:
```yaml theme={null}
tools:
- name: demo
method: POST
endpoint: http://example.com/api/users
args:
- name: username # Header: Username: alice
position: header
- name: traceId # URL: ?traceId=t-123
position: query
- name: avatarUrl # form field: avatarUrl=...
position: form-data
```
Actual request sent to downstream:
```http theme={null}
POST /api/users?traceId=t-123 HTTP/1.1
Host: example.com
Username: alice
Content-Type: multipart/form-data; boundary=---BOUNDARY
---BOUNDARY
Content-Disposition: form-data; name="avatarUrl"
https://img.example.com/1.png
---BOUNDARY--
```
For JSON format request body, assembly is needed in `requestBody`, for example:
```yaml theme={null}
requestBody: |-
{
"isPublic": {{.Args.isPublic}},
"showEmail": {{.Args.showEmail}},
"theme": "{{.Args.theme}}",
"tags": {{.Args.tags}}
}
```
Including `endpoint` (target address) can also use the above sources to extract values, such as `http://localhost:5236/users/{{.Args.email}}/preferences` which extracts values from request parameters.
#### 5.2 Response Parameter Assembly
Response body assembly is similar to request body assembly:
1. `.Response.Data`: Values extracted from response, response must be in JSON format to be extractable
2. `.Response.Body`: Directly pass through the entire response body, ignoring response content format and directly passing to client
Both extract values via `.Response`, for example:
```yaml theme={null}
responseBody: |-
{
"id": "{{.Response.Data.id}}",
"username": "{{.Response.Data.username}}",
"email": "{{.Response.Data.email}}",
"createdAt": "{{.Response.Data.createdAt}}"
}
```
## Configuration Storage
Gateway proxy configuration can be stored in the following two ways:
* Supports SQLite3, PostgreSQL, MySQL
* Each configuration stored as a record
* Supports dynamic updates and hot reloading
* Each configuration stored separately as a YAML file
* Similar to Nginx vhost configuration method
* File name recommended to use service name, such as `mock-server.yaml`
## MCP Service Proxy Configuration
In addition to proxying HTTP services, MCP Gateway also supports proxying MCP services. Currently, stdio, SSE, and streamable-http three transport protocols are all supported.
### Configuration Example
The following is a complete MCP service proxy configuration example:
```yaml theme={null}
name: "proxy-mcp-exp"
tenant: "default"
routers:
- server: "amap-maps"
prefix: "/gateway/stdio-proxy"
cors:
allowOrigins:
- "*"
allowMethods:
- "GET"
- "POST"
- "OPTIONS"
allowHeaders:
- "Content-Type"
- "Authorization"
- "Mcp-Session-Id"
exposeHeaders:
- "Mcp-Session-Id"
allowCredentials: true
- server: "mock-user-sse"
prefix: "/gateway/sse-proxy"
cors:
allowOrigins:
- "*"
allowMethods:
- "GET"
- "POST"
- "OPTIONS"
allowHeaders:
- "Content-Type"
- "Authorization"
- "Mcp-Session-Id"
exposeHeaders:
- "Mcp-Session-Id"
allowCredentials: true
- server: "mock-user-mcp"
prefix: "/gateway/streamable-http-proxy"
cors:
allowOrigins:
- "*"
allowMethods:
- "GET"
- "POST"
- "OPTIONS"
allowHeaders:
- "Content-Type"
- "Authorization"
- "Mcp-Session-Id"
exposeHeaders:
- "Mcp-Session-Id"
allowCredentials: true
mcpServers:
- type: "stdio"
name: "amap-maps"
command: "npx"
args:
- "-y"
- "@amap/amap-maps-mcp-server"
env:
AMAP_MAPS_API_KEY: "{{.Request.Headers.Apikey}}"
- type: "sse"
name: "mock-user-sse"
url: "http://localhost:3000/gateway/user/sse"
- type: "streamable-http"
name: "mock-user-mcp"
url: "http://localhost:3000/gateway/user/mcp"
```
### Configuration Explanation
#### 1. MCP Service Types
MCP Gateway supports the following three types of MCP service proxies:
* Communicate with MCP service processes via standard input/output
* Suitable for MCP services that need local startup, such as third-party SDKs
* Configuration parameters include `command`, `args`, and `env`
* Forward MCP client requests to upstream services supporting SSE
* Suitable for existing MCP services supporting SSE protocol
* Only need to configure `url` parameter pointing to upstream SSE service address
* Forward MCP client requests to upstream services supporting streamable HTTP
* Suitable for existing upstream services supporting MCP protocol
* Only need to configure `url` parameter pointing to upstream MCP service address
#### 2. stdio Type Configuration
stdio type MCP service configuration example:
```yaml theme={null}
mcpServers:
- type: "stdio"
name: "amap-maps" # Service name
command: "npx" # Command to execute
args: # Command arguments
- "-y"
- "@amap/amap-maps-mcp-server"
env: # Environment variables
AMAP_MAPS_API_KEY: "{{.Request.Headers.Apikey}}" # Extract value from request headers
```
Environment variables can be set via the `env` field, supporting value extraction from requests, for example `{{.Request.Headers.Apikey}}` means extract the Apikey value from request headers.
#### 3. SSE Type Configuration
SSE type MCP service configuration example:
```yaml theme={null}
mcpServers:
- type: "sse"
name: "mock-user-sse" # Service name
url: "http://localhost:3000/gateway/user/sse" # Upstream SSE service address, usually ends with /sse, actual depends on upstream service
```
#### 4. streamable-http Type Configuration
streamable-http type MCP service configuration example:
```yaml theme={null}
mcpServers:
- type: "streamable-http"
name: "mock-user-mcp" # Service name
url: "http://localhost:3000/gateway/user/mcp" # Upstream MCP service address, usually ends with /mcp, actual depends on upstream service
```
#### 5. Routing Configuration
For MCP service proxy, routing configuration is similar to HTTP service proxy. CORS should be configured according to actual situation (usually production environments generally do not enable cross-origin):
```yaml theme={null}
routers:
- server: "amap-maps" # Service name, must match name in mcpServers
prefix: "/gateway/stdio-proxy" # Route prefix, globally unique
cors:
allowOrigins:
- "*"
allowMethods:
- "GET"
- "POST"
- "OPTIONS"
allowHeaders:
- "Content-Type"
- "Authorization"
- "Mcp-Session-Id" # MCP service must include this header
exposeHeaders:
- "Mcp-Session-Id" # MCP service must expose this header
allowCredentials: true
```
For MCP services, `Mcp-Session-Id` in request and response headers must be supported, otherwise clients cannot use it normally.
## Advanced Configuration
### Notifier Configuration
Notifier is used to configure reload notifications, supporting multiple methods:
Notify via system signals, suitable for single-machine deployment
```yaml theme={null}
notifier:
type: "signal"
signal:
signal: "SIGHUP"
pid: "/var/run/mcp-gateway.pid"
```
Notify via HTTP API, suitable for remote management
```yaml theme={null}
notifier:
type: "api"
api:
port: 5235
target_url: "http://localhost:5235/_reload"
```
Notify via Redis publish/subscribe, suitable for cluster deployment
```yaml theme={null}
notifier:
type: "redis"
redis:
cluster_type: "single"
addr: "localhost:6379"
topic: "mcp-gateway:reload"
```
### Environment Variable Injection
Environment variables can be used in configuration, supporting default values:
```yaml theme={null}
# Basic syntax
port: ${MCP_GATEWAY_PORT:5235} # Use environment variable, default value 5235
# String format
logger:
level: "${LOGGER_LEVEL:info}" # Use environment variable, default value info
# Use in service configuration
config:
ApiKey: '{{ env "API_KEY" }}'
BaseUrl: '{{ env "API_BASE_URL" "http://localhost:8080" }}' # With default value
```
### Template Functions
In request and response body templates, template functions can be used to handle complex data:
Convert objects or arrays to JSON strings for handling complex data structures
```yaml theme={null}
requestBody: |-
{
"settings": {{ toJSON .Args.settings }},
"notifications": {{ toJSON .Args.notifications }}
}
```
For simple arrays and objects, variables can be used directly
```yaml theme={null}
requestBody: |-
{
"tags": {{.Args.tags}},
"preferences": {{ .Args.preferences }}
}
```
Using the `toJSON` function ensures complex objects and arrays are correctly serialized to JSON format, especially suitable for nested structures and data containing special characters.
### Complex Parameter Processing Example
The following is a complete example of handling complex parameters, showing how to define and use object and array type parameters:
```yaml theme={null}
args:
- name: "settings"
position: "body"
required: false
type: "object"
description: "User custom settings as key-value pairs"
default: "{}"
- name: "notifications"
position: "body"
required: false
type: "array"
description: "User notification preferences"
items:
type: "object"
properties:
type:
type: "string"
description: "Notification type (email, push, sms)"
channel:
type: "string"
description: "Notification channel (marketing, system, security)"
enabled:
type: "boolean"
description: "Whether this notification is enabled"
frequency:
type: "number"
description: "Notification frequency (0: realtime, 1: daily, 2: weekly, 3: monthly)"
default: "[]"
requestBody: |-
{
"settings": {{ toJSON .Args.settings }},
"notifications": {{ .Args.notifications }}
}
responseBody: |-
{
"settings": {{ toJSON .Response.Data.preferences.settings }},
"notifications": {{ toJSON .Response.Data.preferences.notifications }}
}
```
### File Upload Processing
Supports file upload scenarios:
```yaml theme={null}
args:
- name: "file"
position: "form-data"
required: true
type: "string"
description: "File to upload"
- name: "description"
position: "form-data"
required: false
type: "string"
description: "File description"
```
## Best Practices
* Use environment variables to store sensitive information (such as database passwords, API keys)
* Limit CORS Origins in production environments, avoid using "\*"
* Enable OAuth2 authentication and appropriate authorization mechanisms
* Regularly rotate API keys and tokens
* Use encrypted Redis connections to store session data
* Set reasonable timeout and reload intervals
* Use Redis clusters to improve session storage performance
* Choose appropriate log levels, avoid excessive debug logs
* Use connection pools to reduce connection overhead
* Cache frequently called APIs
* Avoid complex calculations in templates
* Use meaningful tool and service names
* Add detailed description information
* Keep configuration files clean and readable
* Configure log rotation to avoid disk space shortage
* Monitor PID files and process status
* Set appropriate notifier types for configuration management convenience
* Regularly check and update configurations
* Thoroughly test configurations in development environments
* Use mock services for integration testing
* Verify all parameters and response formats
* Test error handling and edge cases
## Configuration Validation
Before applying configuration, it is recommended to perform the following validations:
Ensure YAML syntax is correct with no indentation errors
Check if all required environment variables are set
Verify database or Redis connection configuration is correct
Check if all reference relationships are correct, such as server name matching
Verify Go Template syntax and variable references
Ensure all endpoints are accessible
Ensure PID file path has write permissions
For more information on Go Template usage, please refer to [Template Usage Guide](/en/configuration/templates).
# MCP Gateway Configuration
Source: https://docs.unla.amoylab.com/en/configuration/mcp-gateway
Detailed explanation of mcp-gateway.yaml configuration file
Configuration files support using `${VAR:default}` syntax for environment variable injection. If environment variables are not set, default values will be used.
A common practice is to inject through different `.env`, `.env.development`, `.env.prod` files, though you can also directly modify the configuration to hardcode a value.
## Basic Configuration
```yaml theme={null}
port: ${MCP_GATEWAY_PORT:5235} # Service listening port
pid: "${MCP_GATEWAY_PID:/var/run/mcp-gateway.pid}" # PID file path
```
The PID here should be consistent with the PIDs mentioned below, used for service management and hot reload functionality.
## Storage Configuration
The storage configuration module is mainly used to store gateway proxy configuration information. Currently supports two storage methods:
Store in database, each configuration is a record, supports SQLite3, PostgreSQL, MySQL
Store configurations through API endpoints, allowing for external configuration management systems
### Configuration Example
```yaml theme={null}
storage:
type: "${GATEWAY_STORAGE_TYPE:db}" # Storage type: db, api
# Database configuration (used when type is 'db')
database:
type: "${GATEWAY_DB_TYPE:sqlite}" # Database type (sqlite, postgres, mysql)
host: "${GATEWAY_DB_HOST:localhost}" # Database host address
port: ${GATEWAY_DB_PORT:5432} # Database port
user: "${GATEWAY_DB_USER:postgres}" # Database username
password: "${GATEWAY_DB_PASSWORD:example}" # Database password
dbname: "${GATEWAY_DB_NAME:./data/mcp-gateway.db}" # Database name or file path
sslmode: "${GATEWAY_DB_SSL_MODE:disable}" # SSL mode for database connection
# API configuration (used when type is 'api')
api:
url: "${GATEWAY_STORAGE_API_URL:}" # API endpoint URL
configJSONPath: "${GATEWAY_STORAGE_API_CONFIG_JSON_PATH:}" # JSON path for config in API response
timeout: "${GATEWAY_STORAGE_API_TIMEOUT:30s}" # Request timeout
```
## Notification Configuration
The notification configuration module is mainly used to let `mcp-gateway` detect updates and perform hot reloads without restarting the service when configuration updates occur.
### Supported Notification Methods
Notify by sending operating system signals, similar to `kill -SIGHUP ` or `nginx -s reload`
Notify by calling an API, `mcp-gateway` will listen on an independent port
Notify through redis publish/subscribe functionality, suitable for single machine or cluster deployment
Composite notification, combining multiple methods, `signal` and `api` are always enabled by default
### Notification Role Description
Responsible for sending notifications, `apiserver` can only use this mode
Responsible for receiving notifications, standalone `mcp-gateway` is recommended to use only this mode
Both sender and receiver, cluster deployed `mcp-gateway` can use this approach
### Configuration Example
```yaml theme={null}
notifier:
role: "${NOTIFIER_ROLE:receiver}" # Role: 'sender' or 'receiver'
type: "${NOTIFIER_TYPE:signal}" # Type: 'signal', 'api', 'redis' or 'composite'
# Signal configuration (used when type is 'signal')
signal:
signal: "${NOTIFIER_SIGNAL:SIGHUP}" # Signal to send
pid: "${NOTIFIER_SIGNAL_PID:/var/run/mcp-gateway.pid}" # PID file path
# API configuration (used when type is 'api')
api:
port: ${NOTIFIER_API_PORT:5235} # API port
target_url: "${NOTIFIER_API_TARGET_URL:http://localhost:5235/_reload}" # Reload endpoint
# Redis configuration (used when type is 'redis')
redis:
addr: "${NOTIFIER_REDIS_ADDR:localhost:6379}" # Redis address
password: "${NOTIFIER_REDIS_PASSWORD:UseStrongPasswordIsAGoodPractice}" # Redis password
db: ${NOTIFIER_REDIS_DB:0} # Redis database number
topic: "${NOTIFIER_REDIS_TOPIC:mcp-gateway:reload}" # Redis publish/subscribe topic
```
## Session Storage Configuration
Session storage configuration is used to store session information in MCP. Different storage methods can be chosen based on different deployment scenarios:
Memory storage, suitable for single machine deployment (note: restart will lose session information)
Redis storage, suitable for single machine or cluster deployment, supports persistence
### Configuration Example
```yaml theme={null}
session:
type: "${SESSION_STORAGE_TYPE:memory}" # Storage type: memory, redis
redis:
addr: "${SESSION_REDIS_ADDR:localhost:6379}" # Redis address
password: "${SESSION_REDIS_PASSWORD:}" # Redis password
db: ${SESSION_REDIS_DB:0} # Redis database number
topic: "${SESSION_REDIS_TOPIC:mcp-gateway:session}" # Redis publish/subscribe topic
```
When using memory storage, service restart will cause all session information to be lost. Redis storage is recommended for production environments.
## Forward Headers Configuration
The forward headers configuration allows the MCP Gateway to forward HTTP headers from client requests to downstream services. This feature is useful for authentication, request tracing, and custom header propagation.
Forward headers functionality is disabled by default for backward compatibility. Enable it by setting `enabled: true` in the configuration.
### Features
Control which headers are forwarded using allow/ignore lists with case-insensitive matching
Forward headers from client requests (tools/list and tools/call) to downstream services
Support forwarding headers passed as tool arguments via configurable parameter names
Choose whether to override existing headers or add to them
### Configuration Options
```yaml theme={null}
forward:
enabled: ${FORWARD_ENABLED:false} # Enable forward headers (default: false)
mcp_arg:
key_for_header: "${FORWARD_MCP_ARG_KEY_FOR_HEADER:__forwardHeaders}" # Parameter name for tool arguments
header:
allow_headers: "${FORWARD_ALLOW_HEADERS:}" # Comma-separated list of allowed headers (takes priority)
ignore_headers: "${FORWARD_IGNORE_HEADERS:Accept, Accept-Encoding, Accept-Language, Host, Cookie, Connection, User-Agent, Content-Length, Content-Type}" # Headers to ignore
case_insensitive: ${FORWARD_HEADER_CASE_INSENSITIVE:true} # Case insensitive header matching
override_existing: ${FORWARD_HEADER_OVERRIDE_EXISTING:false} # Override existing headers instead of adding
```
### Header Filtering Logic
The filtering logic follows a priority-based approach:
If `allow_headers` is configured (non-empty), it takes priority and `ignore_headers` is completely ignored
When `allow_headers` is set, only headers in this list are forwarded, all others are ignored
When `allow_headers` is empty, headers in `ignore_headers` list are filtered out, others are forwarded
Header matching respects the `case_insensitive` setting for both allow and ignore lists
### Usage Examples
#### Example 1: Allow Only Specific Headers
```yaml theme={null}
forward:
enabled: true
header:
allow_headers: "Authorization, X-API-Key, X-Request-ID"
ignore_headers: "Host, Cookie" # This will be ignored
case_insensitive: true
```
**Result**: Only `Authorization`, `X-API-Key`, and `X-Request-ID` headers are forwarded.
#### Example 2: Block Specific Headers
```yaml theme={null}
forward:
enabled: true
header:
allow_headers: "" # Empty - use ignore list instead
ignore_headers: "Accept, Host, Cookie, User-Agent"
case_insensitive: true
```
**Result**: All headers except `Accept`, `Host`, `Cookie`, and `User-Agent` are forwarded.
#### Example 3: Tool Argument Headers
```yaml theme={null}
forward:
enabled: true
mcp_arg:
key_for_header: "custom_headers"
header:
override_existing: true
```
Tools can now pass headers via the `custom_headers` argument:
```json theme={null}
{
"name": "api_call",
"arguments": {
"url": "https://api.example.com/data",
"custom_headers": {
"Authorization": "Bearer token123",
"X-Custom-Header": "value"
}
}
}
```
### Environment Variables
All forward headers settings can be configured via environment variables:
```bash theme={null}
# Enable the feature
FORWARD_ENABLED=true
# Configure header forwarding behavior
FORWARD_MCP_ARG_KEY_FOR_HEADER=__forwardHeaders
FORWARD_ALLOW_HEADERS="Authorization, X-API-Key"
FORWARD_IGNORE_HEADERS="Accept, Host, Cookie"
FORWARD_HEADER_CASE_INSENSITIVE=true
FORWARD_HEADER_OVERRIDE_EXISTING=false
```
When enabling forward headers in production, carefully review which headers should be forwarded to avoid security risks such as exposing sensitive authentication tokens or cookies.
## Tracing (OpenTelemetry → Jaeger)
MCP Gateway supports distributed tracing via OpenTelemetry and exports to Jaeger. This is optional and disabled by default.
### What You Get
* Inbound HTTP requests are traced via Gin instrumentation (health check is excluded)
* Downstream HTTP calls propagate trace context automatically
* Optional capture of downstream request fields/body and error previews for faster debugging
### Configuration
```yaml theme={null}
tracing:
enabled: ${TRACING_ENABLED:false}
service_name: "${TRACING_SERVICE_NAME:mcp-gateway}"
endpoint: "${TRACING_ENDPOINT:localhost:4317}" # Jaeger OTLP collector: gRPC(4317) or HTTP(4318)
protocol: "${TRACING_PROTOCOL:grpc}" # grpc or http
insecure: ${TRACING_INSECURE:true}
sampler_rate: ${TRACING_SAMPLER_RATE:0.1} # 0.0 ~ 1.0
environment: "${TRACING_ENV:dev}"
headers: {} # optional exporter headers
capture:
downstream_error:
enabled: ${TRACING_ERR_BODY_ENABLED:false}
max_body_length: ${TRACING_ERR_BODY_MAX_LEN:256}
# GLOBAL capture settings — use with care to avoid leaking secrets.
downstream_request:
enabled: ${TRACING_REQ_ARGS_ENABLED:false}
body_enabled: ${TRACING_REQ_BODY_ENABLED:false}
body_max_length: ${TRACING_REQ_BODY_MAX_LEN:256}
max_field_length: ${TRACING_REQ_ARG_MAX_LEN:256}
include_fields: "${TRACING_INCLUDE_FIELDS:}" # CSV or JSON map of key=template
```
### Environment Variables
```bash theme={null}
# Enable tracing and set service metadata
TRACING_ENABLED=true
TRACING_SERVICE_NAME=mcp-gateway
TRACING_ENV=dev
# Exporter options (choose one protocol)
TRACING_PROTOCOL=grpc
TRACING_ENDPOINT=localhost:4317 # for gRPC (OTLP)
# OR
# TRACING_PROTOCOL=http
# TRACING_ENDPOINT=http://localhost:4318 # for HTTP (OTLP)
TRACING_INSECURE=true
TRACING_SAMPLER_RATE=1.0 # 1.0 for dev; lower in prod
# Optional capture controls (use cautiously in prod)
TRACING_ERR_BODY_ENABLED=true
TRACING_ERR_BODY_MAX_LEN=256
TRACING_REQ_ARGS_ENABLED=false
TRACING_INCLUDE_FIELDS="username={{.Args.username}},email={{.Args.email}}"
TRACING_REQ_ARG_MAX_LEN=256
TRACING_REQ_BODY_ENABLED=false
TRACING_REQ_BODY_MAX_LEN=256
```
### Local Jaeger
* Use the provided compose file to start Jaeger locally: `deploy/docker/jaeger/docker-compose.yml`
* Command: `docker compose -f deploy/docker/jaeger/docker-compose.yml up`
* Jaeger UI: [http://localhost:16686](http://localhost:16686)
### Screenshots
Capturing request fields or bodies can expose sensitive data (tokens, passwords, PII). Keep disabled by default, use minimal sampling and narrow field selection in controlled environments.
## Configuration File Location
By default, configuration files should be placed in the following locations:
* Container deployment: `/app/configs/mcp-gateway.yaml`
* Binary deployment: `./configs/mcp-gateway.yaml`
## Hot Reload Mechanism
MCP Gateway supports hot reload configuration, allowing new configurations to be applied without restarting the service:
When configuration changes occur, reload is triggered through configured notification methods (signal, api, redis)
Before reloading, the validity of the new configuration is verified to ensure stable service operation
After validation passes, smoothly switch to the new configuration without interrupting ongoing connections
## Best Practices
* Recommended storage type: `db` with SQLite
* Notification type: `composite` or `signal`
* Session storage: `memory` or `redis`
* Storage type: `db` with PostgreSQL or MySQL
* Notification type: `redis` or `composite`
* Session storage: recommended `redis`
* Use strong passwords to protect Redis and database
* Regularly backup configuration data
* Monitor service health status and performance metrics
# OAuth Login Configuration
Source: https://docs.unla.amoylab.com/en/configuration/oauth-login
Detailed guide for configuring Google and GitHub OAuth login functionality
## Overview
Unla supports user login through third-party OAuth services, currently supporting `Google` and `GitHub` login methods. Users can quickly log in to the Unla Web interface using their existing Google or GitHub accounts without needing to register separately.
Quick login using Google account
Quick login using GitHub account
## Prerequisites
Before configuring OAuth login, you need to create OAuth applications with the respective service providers:
Create OAuth 2.0 client ID in Google Cloud Console
Create OAuth application in GitHub
Configure correct callback URLs for each OAuth application
## Google OAuth Configuration
### 1. Create Google OAuth Application
Visit [Google Cloud Console](https://console.cloud.google.com/) and log in to your account
Create a new project or select an existing project
Enable Google+ API in APIs & Services
Create OAuth 2.0 client ID in the Credentials page, select "Web application" type
Add to "Authorized redirect URIs":
```
https://your-domain.com/api/auth/google/callback
```
### 2. Obtain Credentials
After creation, you will get:
* **Client ID**: Used for `client_id` configuration
* **Client Secret**: Used for `client_secret` configuration
### 3. Configure apiserver.yaml
Add Google OAuth configuration to the `apiserver.yaml` configuration file:
```yaml theme={null}
oauth:
google:
client_id: "your-google-client-id.apps.googleusercontent.com"
client_secret: "your-google-client-secret"
```
It's recommended to use environment variables to manage sensitive information:
```yaml theme={null}
oauth:
google:
client_id: "${OAUTH_GOOGLE_CLIENT_ID:}"
client_secret: "${OAUTH_GOOGLE_CLIENT_SECRET:}"
```
## GitHub OAuth Configuration
### 1. Create GitHub OAuth Application
Go to GitHub Settings → Developer settings → OAuth Apps
Click "New OAuth App" to create a new OAuth application
* **Application name**: Unla Web
* **Homepage URL**: [https://your-domain.com](https://your-domain.com)
* **Authorization callback URL**: [https://your-domain.com/api/auth/github/callback](https://your-domain.com/api/auth/github/callback)
Click "Register application" to complete creation
### 2. Obtain Credentials
After creation, you will get:
* **Client ID**: Used for `client_id` configuration
* **Client Secret**: Need to generate, used for `client_secret` configuration
### 3. Configure apiserver.yaml
Add GitHub OAuth configuration to the `apiserver.yaml` configuration file:
```yaml theme={null}
oauth:
github:
client_id: "your-github-client-id"
client_secret: "your-github-client-secret"
```
It's recommended to use environment variables to manage sensitive information:
```yaml theme={null}
oauth:
github:
client_id: "${OAUTH_GITHUB_CLIENT_ID:}"
client_secret: "${OAUTH_GITHUB_CLIENT_SECRET:}"
```
## Complete Configuration Example
Here's a complete OAuth configuration example:
```yaml theme={null}
oauth:
# Google OAuth Configuration
google:
client_id: "${OAUTH_GOOGLE_CLIENT_ID:}"
client_secret: "${OAUTH_GOOGLE_CLIENT_SECRET:}"
# GitHub OAuth Configuration
github:
client_id: "${OAUTH_GITHUB_CLIENT_ID:}"
client_secret: "${OAUTH_GITHUB_CLIENT_SECRET:}"
# Corresponding environment variable configuration (.env file)
# OAUTH_GOOGLE_CLIENT_ID=your-google-client-id.apps.googleusercontent.com
# OAUTH_GOOGLE_CLIENT_SECRET=your-google-client-secret
# OAUTH_GITHUB_CLIENT_ID=your-github-client-id
# OAUTH_GITHUB_CLIENT_SECRET=your-github-client-secret
```
## Callback URL Configuration
Ensure correct callback URLs are configured in the OAuth applications:
```bash Google OAuth Callback URL theme={null}
https://your-domain.com/api/auth/google/callback
```
```bash GitHub OAuth Callback URL theme={null}
https://your-domain.com/api/auth/github/callback
```
**Important Notes**:
* Callback URLs must match your deployed Unla service domain
* Use HTTPS in production environments
* Don't hardcode sensitive information in code, use environment variables
## Features
### Automatic Account Creation
* Users logging in via OAuth for the first time will have accounts created automatically
* User information (username, email, avatar) will be synced from the OAuth provider
* Subsequent logins will automatically link to the created account
### Account Association
* Supports multiple login methods coexisting (local accounts + OAuth)
* Users can use both local password and OAuth login
* Administrator account functionality is unaffected
### Security
* All OAuth processes follow standard OAuth 2.0 protocol
* Sensitive information (like access tokens) is only processed server-side
* Supports HTTPS encrypted transmission
## FAQ
Check if `client_id` and `client_secret` are properly configured. Login options only appear when the corresponding parameters are configured.
Ensure the callback URL configured in the OAuth application matches the actual deployed domain, including protocol (http/https) and port.
User information is automatically synced on first login. For re-sync, contact administrator or re-login.
Delete or comment out the corresponding OAuth configuration in `apiserver.yaml` to disable the respective login option.
## Environment Variable Reference
| Variable Name | Description | Example |
| ---------------------------- | -------------------------- | -------------------------------------- |
| `OAUTH_GOOGLE_CLIENT_ID` | Google OAuth Client ID | `123456789.apps.googleusercontent.com` |
| `OAUTH_GOOGLE_CLIENT_SECRET` | Google OAuth Client Secret | `GOCSPX-abc123def456` |
| `OAUTH_GITHUB_CLIENT_ID` | GitHub OAuth Client ID | `Iv1.abc123def456` |
| `OAUTH_GITHUB_CLIENT_SECRET` | GitHub OAuth Client Secret | `abc123def456ghi789` |
# Go Template Usage Guide
Source: https://docs.unla.amoylab.com/en/configuration/templates
How to use Go Template to process request and response data in MCP Gateway
This document introduces how to use Go Template to process request and response data in MCP Gateway. Go Template provides powerful template functionality that helps us flexibly handle data transformation and formatting.
## Basic Syntax
Go Template uses `{{}}` as delimiters, and various functions and variables can be used within the delimiters. In MCP Gateway, we mainly use the following variables:
* `.Config`: Service-level configuration
* `.Args`: Request parameters
* `.Request`: Original request information
* `.Response`: Upstream service response information
## Common Use Cases
### 1. Getting Configuration from Environment Variables
```yaml theme={null}
config:
Authorization: 'Bearer {{ env "AUTH_TOKEN" }}' # Get configuration from environment variables
```
Using the `env` function allows you to safely retrieve sensitive information from environment variables, avoiding hardcoding in configuration files.
### 2. Extracting Values from Request Headers
```yaml theme={null}
headers:
Authorization: "{{.Request.Headers.Authorization}}" # Pass through client's Authorization header
Cookie: "{{.Config.Cookie}}" # Use value from service configuration
```
### 3. Building Request Body
```yaml theme={null}
requestBody: |-
{
"username": "{{.Args.username}}",
"email": "{{.Args.email}}"
}
```
### 4. Processing Response Data
```yaml theme={null}
responseBody: |-
{
"id": "{{.Response.Data.id}}",
"username": "{{.Response.Data.username}}",
"email": "{{.Response.Data.email}}",
"createdAt": "{{.Response.Data.createdAt}}"
}
```
### 5. Handling Nested Response Data
For complex nested data structures, you can access them layer by layer:
```yaml theme={null}
responseBody: |-
{
"id": "{{.Response.Data.id}}",
"username": "{{.Response.Data.username}}",
"email": "{{.Response.Data.email}}",
"createdAt": "{{.Response.Data.createdAt}}",
"preferences": {
"isPublic": {{.Response.Data.preferences.isPublic}},
"showEmail": {{.Response.Data.preferences.showEmail}},
"theme": "{{.Response.Data.preferences.theme}}",
"tags": {{.Response.Data.preferences.tags}}
}
}
```
### 6. Handling Array Data
When you need to process array data in responses, you can use Go Template's range functionality:
```yaml theme={null}
responseBody: |-
{
"total": "{{.Response.Data.total}}",
"rows": [
{{- $len := len .Response.Data.rows -}}
{{- $rows := fromJSON .Response.Data.rows }}
{{- range $i, $e := $rows }}
{
"id": {{ $e.id }},
"detail": "{{ $e.detail }}",
"deviceName": "{{ $e.deviceName }}"
}{{ if lt (add $i 1) $len }},{{ end }}
{{- end }}
]
}
```
This example shows how to:
1. Use the `fromJSON` function to convert JSON strings into traversable objects
2. Use `range` to iterate through arrays
3. Use the `len` function to get array length
4. Use the `add` function for mathematical operations
5. Use conditional statements `if` to control comma separation between array elements
### 7. Using Parameters in URLs
Dynamically building URL paths:
```yaml theme={null}
endpoint: "http://localhost:5236/users/{{.Args.email}}/preferences"
```
### 8. Handling Complex Object Data
When you need to convert complex structures like objects and arrays from requests or responses to JSON, you can use the `toJSON` function:
```yaml theme={null}
requestBody: |-
{
"isPublic": {{.Args.isPublic}},
"showEmail": {{.Args.showEmail}},
"theme": "{{.Args.theme}}",
"tags": {{.Args.tags}},
"settings": {{ toJSON .Args.settings }}
}
```
Here, `settings` is a complex object. Using the `toJSON` function will automatically convert `settings` to a JSON string.
### 9. Safely Access Nested Fields (safeGet/safeGetOr)
When a middle level of a nested object is `null` (or missing), direct access will cause a template rendering error. For example:
```yaml theme={null}
responseBody: |-
{
"id": "{{.Response.Data.id}}",
"username": "{{.Response.Data.username}}",
"email": "{{.Response.Data.email}}",
"createdAt": "{{.Response.Data.createdAt}}",
"theme": "{{.Response.Data.preferences.theme}}" # Will error if preferences is null
}
```
To address this, two functions are added: `safeGet` and `safeGetOr`.
* `safeGet `: Safely reads a nested field; if any middle level is `nil`/missing, returns an empty value (no error).
* `safeGetOr `: Like `safeGet`, but returns `` when access fails.
Example data (normal):
```json theme={null}
{
"id": "28050608-7f39-42cf-be06-4982135dada9",
"username": "2",
"email": "1",
"createdAt": "2025-09-12T11:43:16.086506+08:00",
"preferences": {
"isPublic": false,
"showEmail": true,
"theme": "light",
"tags": [],
"settings": {},
"notifications": []
}
}
```
When `preferences` is `null`:
```json theme={null}
{
"id": "28050608-7f39-42cf-be06-4982135dada9",
"username": "2",
"email": "1",
"createdAt": "2025-09-12T11:43:16.086506+08:00",
"preferences": null
}
```
Then:
```yaml theme={null}
# Using safeGet: no error, renders as empty ()
responseBody: |-
{
"id": "{{.Response.Data.id}}",
"username": "{{.Response.Data.username}}",
"email": "{{.Response.Data.email}}",
"createdAt": "{{.Response.Data.createdAt}}",
"theme": "{{ safeGet "Response.Data.preferences.theme" . }}"
}
# Using safeGetOr: provide a default value
responseBody: |-
{
"id": "{{.Response.Data.id}}",
"username": "{{.Response.Data.username}}",
"email": "{{.Response.Data.email}}",
"createdAt": "{{.Response.Data.createdAt}}",
"theme": "{{ safeGetOr "Response.Data.preferences.theme" . "light" }}"
}
```
## Built-in Functions
Currently supports the following built-in functions:
Get environment variable values
```yaml theme={null}
Authorization: 'Bearer {{ env "AUTH_TOKEN" }}'
```
Perform integer addition operations
```yaml theme={null}
{{ if lt (add $i 1) $len }},{{ end }}
```
Convert JSON strings to traversable objects
```yaml theme={null}
{{- $rows := fromJSON .Response.Data.rows }}
```
Convert objects to JSON strings
```yaml theme={null}
"settings": {{ toJSON .Args.settings }}
```
Safely read nested fields; if any middle level is `nil` or missing, return an empty value without error.
```yaml theme={null}
{{ safeGet "Response.Data.preferences.theme" . }}
```
Like `safeGet`, but returns a default value when access fails.
```yaml theme={null}
{{ safeGetOr "Response.Data.preferences.theme" . "light" }}
```
## Template Debugging Tips
During development, you can view actual values of template variables through logs
For complex templates, it's recommended to first build a simple version, then gradually add complex logic
Ensure templates work correctly under various data conditions, including empty values, null values, etc.
## Best Practices
* Avoid directly exposing sensitive information in templates
* Use environment variables to store keys and passwords
* Properly validate and escape user input
* Avoid complex calculations in templates
* Use caching mechanisms appropriately
* For large data processing, consider preprocessing in upstream services
* Keep templates concise and clear
* Add appropriate comments and explanations
* Use meaningful variable names
## Extension Features
If you need to add new template functions, you can:
1. **Describe specific use cases**, create an issue explaining the requirements
2. **Welcome PR after implementation**, but currently only accept general-purpose functions
## More Resources
View complete Go Template documentation and advanced usage
# Binary Deployment
Source: https://docs.unla.amoylab.com/en/deployment/binary
Deploy MCP Gateway using binary files
## Supported Platforms
Currently supports binary deployment for the following platforms:
Suitable for x86\_64 architecture Linux systems
Suitable for ARM64 architecture Linux systems
You can view and download the latest binary files at [GitHub Releases](https://github.com/amoylab/unla/releases).
## Deployment Steps
```bash theme={null}
mkdir -p unla/{configs,data}
cd unla/
curl -sL https://raw.githubusercontent.com/amoylab/unla/refs/heads/main/configs/apiserver.yaml -o configs/apiserver.yaml
curl -sL https://raw.githubusercontent.com/amoylab/unla/refs/heads/main/configs/mcp-gateway.yaml -o configs/mcp-gateway.yaml
curl -sL https://raw.githubusercontent.com/amoylab/unla/refs/heads/main/.env.example -o .env
```
On macOS, `/var/run/mcp-gateway.pid` may not have write permissions, so the path needs to be adjusted.
```bash theme={null}
sed -i 's|/var/run/mcp-gateway.pid|./data/mcp-gateway.pid|g' .env
```
Choose the appropriate binary file based on your system architecture:
**Linux AMD64:**
```bash theme={null}
LATEST_VERSION=$(curl -s https://api.github.com/repos/amoylab/unla/releases/latest | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
curl -sL "https://github.com/amoylab/unla/releases/download/${LATEST_VERSION}/mcp-gateway-linux-amd64" -o mcp-gateway
chmod +x mcp-gateway
```
**Linux ARM64:**
```bash theme={null}
LATEST_VERSION=$(curl -s https://api.github.com/repos/amoylab/unla/releases/latest | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
curl -sL "https://github.com/amoylab/unla/releases/download/${LATEST_VERSION}/mcp-gateway-linux-arm64" -o mcp-gateway
chmod +x mcp-gateway
```
```bash theme={null}
./mcp-gateway
```
## Configuration Guide
### Environment Variables File
The downloaded `.env` file contains all necessary configuration items. Main configurations include:
Configure database connection information for storing chat messages and gateway configurations
Configure notification methods for configuration updates (signal, api, redis, etc.)
Configure JWT secret keys and super admin account information
### Configuration Files
* `configs/apiserver.yaml`: API server configuration
* `configs/mcp-gateway.yaml`: MCP Gateway core configuration
For detailed configuration instructions, please refer to the [Configuration Documentation](/en/configuration/apiserver).
## Notes
Binary deployment requires you to manage service startup, stop, and monitoring yourself. It is recommended to use process management tools such as systemd or supervisor in production environments.
### systemd Service Configuration Example
You can create a systemd service file to manage MCP Gateway:
```ini theme={null}
[Unit]
Description=MCP Gateway
After=network.target
[Service]
Type=simple
User=mcpgateway
WorkingDirectory=/opt/unla
ExecStart=/opt/unla/mcp-gateway
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
```
Save this file as `/etc/systemd/system/mcp-gateway.service`, then:
```bash theme={null}
sudo systemctl daemon-reload
sudo systemctl enable mcp-gateway
sudo systemctl start mcp-gateway
```
### Firewall Configuration
Ensure the following ports are accessible:
* `5235`: MCP Gateway main service port
* `5335`: Management port (internal access only)
If you need a Web management interface, it is recommended to deploy API Server and Web frontend simultaneously, or use the [All-in-One Docker deployment](/en/deployment/docker#all-in-one-deployment) method.
# Docker Deployment
Source: https://docs.unla.amoylab.com/en/deployment/docker
Complete guide for deploying MCP Gateway using Docker
## Image Description
MCP Gateway provides two deployment methods:
All services packaged in one container, suitable for single machine deployment or local use
Each service deployed independently, suitable for production or cluster deployment
### Image Repositories
Images are published to the following three repositories:
* **Docker Hub**: `docker.io/ifuryst/unla-*`
* **GitHub Container Registry**: `ghcr.io/amoylab/unla/*`
* **Alibaba Cloud Container Registry**: `registry.ap-southeast-1.aliyuncs.com/amoylab/unla-*`
GHCR supports multi-level directories, so the organization structure is clearer. Docker and Aliyun repositories only support single-level directories, so image names are joined with `-`.
### Image Tags
* `latest`: Latest version
* `vX.Y.Z`: Specific version number
MCP Gateway is currently in rapid iteration! Therefore, it is recommended to deploy with version numbers for better reliability.
### Available Images
```bash theme={null}
# All-in-One version
docker pull docker.io/ifuryst/unla-allinone:latest
docker pull ghcr.io/amoylab/unla/allinone:latest
docker pull registry.ap-southeast-1.aliyuncs.com/amoylab/unla-allinone:latest
# API Server
docker pull docker.io/ifuryst/unla-apiserver:latest
docker pull ghcr.io/amoylab/unla/apiserver:latest
docker pull registry.ap-southeast-1.aliyuncs.com/amoylab/unla-apiserver:latest
# MCP Gateway
docker pull docker.io/ifuryst/unla-mcp-gateway:latest
docker pull ghcr.io/amoylab/unla/mcp-gateway:latest
docker pull registry.ap-southeast-1.aliyuncs.com/amoylab/unla-mcp-gateway:latest
# Mock User Service
docker pull docker.io/ifuryst/unla-mock-server:latest
docker pull ghcr.io/amoylab/unla/mock-server:latest
docker pull registry.ap-southeast-1.aliyuncs.com/amoylab/unla-mock-server:latest
# Web frontend
docker pull docker.io/ifuryst/unla-web:latest
docker pull ghcr.io/amoylab/unla/web:latest
docker pull registry.ap-southeast-1.aliyuncs.com/amoylab/unla-web:latest
```
## All-in-One Deployment
All-in-One deployment packages all services in one container, suitable for single machine deployment or local use. It includes the following services:
* **API Server**: Management platform backend, can be understood as the control plane
* **MCP Gateway**: Core service, responsible for actual gateway service, can be understood as the data plane
* **Mock User Service**: Mock user service, providing test user services
* **Web Frontend**: Management platform frontend, providing visual management interface
* **Nginx**: Reverse proxy for other services
Uses Supervisor to manage service processes, all logs are output to stdout.
### Port Description
* `8080`: Web interface port
* `5235`: MCP Gateway port
* `5234`: API Server port
* `5335`: MCP Gateway management port
* `5236`: Mock User Service port
`5335` is the MCP Gateway management port, hosting internal interfaces such as reload. Do not expose it externally in production environments!
### Data Persistence
It is recommended to mount the following directories:
* `/app/configs`: Configuration file directory
* `/app/data`: Data directory
* `/app/.env`: Environment variable file
### Deployment Steps
```bash theme={null}
mkdir -p unla/{configs,data}
cd unla/
curl -sL https://raw.githubusercontent.com/amoylab/unla/refs/heads/main/configs/apiserver.yaml -o configs/apiserver.yaml
curl -sL https://raw.githubusercontent.com/amoylab/unla/refs/heads/main/configs/mcp-gateway.yaml -o configs/mcp-gateway.yaml
curl -sL https://raw.githubusercontent.com/amoylab/unla/refs/heads/main/.env.example -o .env.allinone
```
```bash theme={null}
# Use Aliyun Container Registry image (recommended for use within China)
docker run -d \
--name unla \
-p 8080:80 \
-p 5234:5234 \
-p 5235:5235 \
-p 5335:5335 \
-p 5236:5236 \
-e ENV=production \
-v $(pwd)/configs:/app/configs \
-v $(pwd)/data:/app/data \
-v $(pwd)/.env.allinone:/app/.env \
--restart unless-stopped \
registry.ap-southeast-1.aliyuncs.com/amoylab/unla-allinone:latest
# Use GitHub Container Registry image
docker run -d \
--name unla \
-p 8080:80 \
-p 5234:5234 \
-p 5235:5235 \
-p 5335:5335 \
-p 5236:5236 \
-e ENV=production \
-v $(pwd)/configs:/app/configs \
-v $(pwd)/data:/app/data \
-v $(pwd)/.env.allinone:/app/.env \
--restart unless-stopped \
ghcr.io/amoylab/unla/allinone:latest
```
### Notes
1. Ensure configuration files and environment variable files are correctly configured
2. Strongly recommended to use strong passwords in production environments
3. Do not expose management port `5335` externally
1. Recommended to use version number tags instead of latest
2. Production environments should configure appropriate resource limits
Ensure mounted directories have correct permissions
## Multi-Container Deployment
Multiple services deployed independently, suitable for production environments or cluster deployment. Includes the following services:
* **mcp-gateway**: Core service, responsible for actual gateway service, can be understood as the data plane
* **web(includes apiserver)**: Management platform and backend, can be understood as the control plane
* **mock-server**: Mock service, providing test services
Suitable for production environments, can be deployed as needed, especially for `mcp-gateway` which can be deployed in multiple replicas for high availability.
### Deployment Features
Uses PostgreSQL as database to store sessions, proxy configurations and other information
Uses Redis for configuration update notifications, OAuth storage and other purposes
Supports multi-replica deployment and load balancing configuration
### Docker Compose Deployment
```bash theme={null}
curl -sL https://raw.githubusercontent.com/amoylab/unla/refs/heads/main/deploy/docker/multi/docker-compose.yml -o docker-compose.yml
curl -sL https://raw.githubusercontent.com/amoylab/unla/refs/heads/main/.env.example -o .env
```
Edit `docker-compose.yml` and `.env` files:
1. Modify database and Redis account passwords
2. Adjust exposed ports as needed
3. Configure LLM service parameters
```bash theme={null}
docker compose up -d
```
Configure Nginx or other LB layers as needed
### Example Configuration
```yaml theme={null}
services:
postgres:
image: postgres:16
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: "**********"
POSTGRES_DB: mcp-gateway
volumes:
- ./db:/var/lib/postgresql/data
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
restart: always
redis:
image: redis:7
ports:
- "6379:6379"
volumes:
- ./redis:/data
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
command: redis-server --appendonly yes --save "900 1" --save "300 10" --save "60 10000" --requirepass "**********"
restart: always
web:
image: ghcr.io/amoylab/unla/web:latest
ports:
- "8080:80"
- "5234:5234"
environment:
- ENV=production
- TZ=Asia/Shanghai
volumes:
- ./.env:/app/.env
- ./data:/app/data
depends_on:
- postgres
- mcp-gateway
- mock-server
restart: always
mcp-gateway:
image: ghcr.io/amoylab/unla/mcp-gateway:latest
ports:
- "5235:5235"
environment:
- ENV=production
- TZ=Asia/Shanghai
volumes:
- ./.env:/app/.env
- ./data:/app/data
depends_on:
- postgres
restart: always
mock-server:
image: ghcr.io/amoylab/unla/mock-server:latest
ports:
- "5236:5236"
environment:
- ENV=production
- TZ=Asia/Shanghai
volumes:
- ./.env:/app/.env
depends_on:
- postgres
restart: always
```
```nginx theme={null}
server {
server_name unla.amoylab.com;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
}
location /api/ {
proxy_pass http://127.0.0.1:5234/api/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /ws/ {
proxy_pass http://127.0.0.1:5234/api/ws/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /gateway/ {
proxy_pass http://127.0.0.1:5235/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
proxy_cache off;
chunked_transfer_encoding off;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
location /mock/ {
proxy_pass http://127.0.0.1:5236/;
proxy_set_header Host $host;
}
}
```
### Important Access URLs
After configuration is complete, you can access the services through the following URLs:
* **Web Management Interface**: [https://unla.amoylab.com/](https://unla.amoylab.com/)
* **MCP Gateway**: [https://unla.amoylab.com/gateway/](https://unla.amoylab.com/gateway/)\*
* **Example MCP Endpoint**: [https://unla.amoylab.com/gateway/user/mcp](https://unla.amoylab.com/gateway/user/mcp)
Please adjust the above URLs according to your actual domain and configuration.
# Kubernetes Deployment
Source: https://docs.unla.amoylab.com/en/deployment/k8s
Deploy MCP Gateway in Kubernetes cluster
## Deployment Overview
MCP Gateway supports deployment in Kubernetes clusters, suitable for large-scale production environments. K8s deployment has the following advantages:
Supports multi-replica deployment with automatic failover
Automatically adjusts instance count based on load
Automatic service registration and load balancing
## Deployment Architecture
Recommended to use microservice architecture for K8s deployment:
```mermaid theme={null}
graph TB
LB[Load Balancer] --> WEB[Web Frontend]
LB --> API[API Server]
LB --> GW[MCP Gateway]
API --> DB[PostgreSQL]
GW --> DB
API --> REDIS[Redis]
GW --> REDIS
subgraph "Kubernetes Cluster"
WEB
API
GW
DB
REDIS
end
```
## Quick Start
### Deploy with kubectl
Download all K8s related deployment files from GitHub:
```bash theme={null}
# Clone project or download deployment file directory
git clone https://github.com/AmoyLab/Unla.git
cd Unla/deploy/k8s/multi
```
```bash theme={null}
kubectl apply -f .
```
```bash theme={null}
# Deploy database and other dependency services
kubectl apply -f deps
```
```bash theme={null}
# Deploy core application services
kubectl apply -f base
```
Choose the appropriate gateway based on your environment:
**Using Traefik:**
```bash theme={null}
kubectl apply -f traefik
```
**Or using Nginx Ingress:**
```bash theme={null}
kubectl apply -f ingress
```
This deployment method supports multi-replica high availability deployment. Other custom configurations can be adjusted in the downloaded YAML files.
## Troubleshooting
### Common Issues
Check if ConfigMap and Secret configurations are correct:
```bash theme={null}
kubectl describe pod -n mcp-gateway
kubectl logs -n mcp-gateway
```
Verify database service and connection configuration:
```bash theme={null}
kubectl get svc -n mcp-gateway
kubectl exec -it -n mcp-gateway -- nc -zv postgres 5432
```
Check Service and network policies:
```bash theme={null}
kubectl get svc,endpoints -n mcp-gateway
kubectl describe networkpolicy -n mcp-gateway
```
## Contribution Guide
We welcome community contributions to improve Kubernetes deployment documentation and configuration files! If you have experience or suggestions, please:
1. Visit the [GitHub project](https://github.com/amoylab/unla)
2. Submit Issues or Pull Requests
3. Share your deployment experience
Your contributions will help more users successfully deploy MCP Gateway in K8s environments! ❤️
# System Architecture
Source: https://docs.unla.amoylab.com/en/development/architecture
Overall architecture design and module description of MCP Gateway system
Overview of the overall architecture of MCP Gateway system, including the gateway itself, management backend, supporting APIs, storage mechanisms, and integration methods with external services.
## Architecture Diagram
The architecture diagram is being updated and will provide detailed system architecture diagrams in future versions.
## Core Modules
### MCP Gateway (mcp-gateway)
MCP Gateway is the core component of the system, responsible for handling all MCP protocol requests:
* **Unified Entry**: `/*` listens to all HTTP requests
* **Route Distribution**: Dynamic request distribution based on route prefix
* **Protocol Parsing**: Parse JSON-RPC format requests
* **Tool Distribution**: Parse tool names and construct call parameters
#### Main Functions
Request distribution based on route prefix and suffix (`/sse`, `/message`, `/mcp`)
Parse JSON-RPC format to extract methods and parameters
Invoke external services and parse results
Dynamically load and apply configuration information
### Management Backend (web)
Provides a visual management interface with the following core modules:
Used to configure MCP gateway proxies and tools, supporting graphical configuration interface
Simple Chat for testing MCP, mainly provided for developers and users who need to integrate into custom systems for reference
User permissions, information maintenance, and access control
### Management Backend Service (apiserver)
Provides complete backend API services:
* Configuration management API
* User interface management
* Chat history queries
* Configuration write storage
* Hot update notifications
* Permission control
### Storage System
#### Configuration Storage
Stores all MCP services, tools, routing and other configuration information:
Lightweight database, suitable for single-machine deployment and development
Production-grade databases, suitable for multi-node deployment
Enterprise-grade database, suitable for production environments
#### Web Data Storage
Stores user data, session records, etc.:
* User account information
* Chat session history
* System configuration data
* Operation log records
### External Service Integration
MCP Gateway is designed for seamless integration with existing business systems:
Supports standard REST API calls, including GET, POST, PUT, DELETE and other methods
Supports Webhook callbacks and event trigger mechanisms
Can directly integrate with existing database systems, supporting multiple database types
## Data Flow
MCP Client sends requests to specified endpoints of MCP Gateway
Gateway parses MCP protocol format and extracts tool invocation information
Look up corresponding configuration information based on tool name
Call backend services using configured templates and parameters
Process backend service responses and convert to MCP protocol format
Return processing results to MCP Client
## Deployment Architecture
### Single Machine Deployment
All services run on the same machine, suitable for development and testing environments
### Distributed Deployment
Each component is deployed independently, supporting horizontal scaling and load balancing
Use Docker and Kubernetes for containerized deployment
## Extensibility Design
MCP Gateway adopts a modular design and supports the following extensions:
* **Protocol Extensions**: Support for new MCP protocol versions
* **Storage Extensions**: Support for new storage backends
* **Authentication Extensions**: Support for multiple authentication mechanisms
* **Monitoring Extensions**: Integration with various monitoring and logging systems
To deeply understand the specific implementation of each component, please refer to the corresponding configuration documentation and development guides.
# Local Development Environment
Source: https://docs.unla.amoylab.com/en/development/local-development
How to set up and start a complete MCP Gateway development environment locally
This document describes how to set up and start a complete MCP Gateway development environment locally, including starting all necessary service components.
## Prerequisites
Before getting started, please ensure your system has the following software installed:
Version control tool
Go programming language environment
JavaScript runtime environment (includes npm)
## Project Architecture Overview
The MCP Gateway project consists of the following core components:
Provides API services for configuration management, user interfaces, etc.
Core gateway service that handles MCP protocol conversion
Mock user service for development testing
Management interface frontend
## Environment Setup Steps
### 1. Get Source Code
Visit the [MCP Gateway code repository](https://github.com/amoylab/unla), click the `Fork` button to fork the project to your GitHub account
```bash theme={null}
git clone https://github.com/your-github-username/unla.git
cd unla
```
### 2. Install Dependencies
```bash theme={null}
go mod tidy
```
```bash theme={null}
cd web
npm i
cd ..
```
### 3. Configure Environment
```bash theme={null}
cp .env.example .env
```
```bash theme={null}
cd web
cp .env.example .env
cd ..
```
You can start development without modifying anything, using the default configuration. You can also modify configuration files to meet your environment or development needs, such as switching between DB and API storage methods.
## Start Development Services
You need 4 terminal windows to run all services. This approach of running multiple services on the host machine allows for easy restart and debugging during development.
### Terminal 1: Start mcp-gateway
```bash theme={null}
go run cmd/gateway/main.go
```
mcp-gateway will start by default on `http://localhost:5235` for handling MCP protocol requests.
### Terminal 2: Start apiserver
```bash theme={null}
go run cmd/apiserver/main.go
```
apiserver will start by default on `http://localhost:5234`.
### Terminal 3: Start mock-server
```bash theme={null}
go run cmd/mock-server/main.go
```
* mock-server will start by default on `http://localhost:5236`
* mock-server-sse will start by default on `http://localhost:5237`
### Terminal 4: Start web frontend
```bash theme={null}
cd web
npm run dev
```
After running the command in the web terminal, it will display the access address.
## Access Management Interface
After startup is complete, you can access the management interface in your browser using the address shown in the terminal.
* Username: Determined by environment variable `SUPER_ADMIN_USERNAME`
* Password: Determined by environment variable `SUPER_ADMIN_PASSWORD`
After logging in, you can modify the username and password in the management interface
## Common Issues
### Environment Variable Settings
Some services may require specific environment variables to work properly. You can set these variables in the `.env` file:
```bash theme={null}
# Example environment variables
APISERVER_JWT_SECRET_KEY="changeme-please-generate-a-random-secret"
SUPER_ADMIN_USERNAME="admin"
SUPER_ADMIN_PASSWORD="changeme-please-use-a-secure-password"
```
### Port Conflicts
If you encounter port conflicts, you can modify port configuration in environment variables:
```bash theme={null}
MCP_GATEWAY_PORT=5235
APISERVER_PORT=5234
MOCK_SERVER_PORT=5236
```
### Dependency Issues
If you encounter dependency installation issues:
```bash theme={null}
go clean -modcache
go mod tidy
```
```bash theme={null}
cd web
rm -rf node_modules package-lock.json
npm install
```
## Development Workflow
### Code Contribution Process
```bash theme={null}
git remote add upstream git@github.com:amoylab/unla.git
```
```bash theme={null}
git pull upstream main
```
```bash theme={null}
git switch -c feat/your-feature-name
```
```bash theme={null}
git push origin feat/your-feature-name
```
Create a Pull Request on GitHub to merge your branch into the main repository's main branch
### Branch Naming Conventions
Use `feat/` prefix, such as `feat/add-auth-module`
Use `fix/` prefix, such as `fix/memory-leak`
### Development Considerations
Before submitting a PR, ensure your code passes all tests
Keep your fork repository synchronized with the upstream repository to avoid code conflicts
Follow the project's code standards and commit message format
## Next Steps
After successfully starting the local development environment, you can:
View architecture documentation to deeply understand system components
Read configuration guide to learn how to configure the gateway
# Unla - MCP Gateway
Source: https://docs.unla.amoylab.com/en/index
🚀 Transform your existing MCP services and APIs into MCP-compliant services through configuration — no code changes required
## What is Unla?
**Unla** is a lightweight, highly available gateway service written in Go. It enables individuals and organizations to transform existing MCP services and APIs into [MCP protocol](https://modelcontextprotocol.io/) compliant services through configuration — without changing a single line of code.
⚡ **Note**: Unla is under rapid development! We strive to maintain backward compatibility, but cannot guarantee 100%. Please carefully check version changes when upgrading. Due to rapid iteration, documentation updates may sometimes lag behind. If you encounter any issues, feel free to seek help through [Discord](https://discord.gg/udf69cT9TY) or [Issues](https://github.com/amoylab/unla/issues) ❤️
## 🔧 Core Design Principles
Platform-agnostic, supports deployment on bare metal, VMs, ECS, Kubernetes environments without modifying existing infrastructure
Transform traditional APIs into MCP services using YAML configuration — no code required
Designed for minimal resource usage without sacrificing performance or availability
Out-of-the-box web interface that simplifies setup and reduces operational overhead
## Architecture
## 🚀 Core Features
### 🔌 Protocol & Proxy Capabilities
* ✅ Support for converting RESTful APIs to MCP services
* ✅ Support for proxying MCP services
* ✅ Support for MCP SSE
* ✅ Support for MCP Streamable HTTP
* ✅ Support for MCP responses including text, images, and audio
* 🔄 Support for converting gRPC to MCP services (in development)
* 🔄 Support for converting WebSocket to MCP services (in development)
### 🧠 Session & Multi-tenancy Support
* ✅ Persistent and recoverable session support
* ✅ Multi-tenancy support
* 🔄 Support for MCP service grouping and aggregation (in development)
### 🛠 Configuration & Management
* ✅ Automatic configuration retrieval and seamless hot reload
* ✅ Configuration persistence (SQLite/PostgreSQL/MySQL/API)
* ✅ Configuration synchronization via OS signals, HTTP, or Redis PubSub
* ✅ Configuration version control
### 🔐 Security & Authentication
* ✅ OAuth-based MCP service pre-authentication support
### 📦 Deployment & Operations
* ✅ Multi-replica service support
* ✅ Docker support
* ✅ Kubernetes and Helm deployment support
Quickly deploy and start Unla MCP Gateway service
Container deployment solution using Docker
Configure MCP Gateway service parameters and options
Seamless integration with multiple MCP clients
## 🌐 Community & Support
Join our Discord community for real-time support
Submit issues and feature requests
View complete online documentation
# Quick Start
Source: https://docs.unla.amoylab.com/en/quickstart
Complete deployment and configuration guide for Unla (MCP Gateway)
## One-Click MCP Gateway Launch
> All service configuration parameters can be changed through environment variable injection
Please note that the following environment variables need to be modified (other environment variables should be adjusted according to your actual situation):
```bash theme={null}
export APISERVER_JWT_SECRET_KEY="changeme-please-generate-a-random-secret"
export SUPER_ADMIN_USERNAME="admin"
export SUPER_ADMIN_PASSWORD="changeme-please-use-a-secure-password"
```
## GHCR Image
Using GitHub Container Registry image:
```bash theme={null}
docker run -d \
--name unla \
-p 8080:80 \
-p 5234:5234 \
-p 5235:5235 \
-p 5335:5335 \
-p 5236:5236 \
-e ENV=production \
-e TZ=Asia/Shanghai \
-e APISERVER_JWT_SECRET_KEY=${APISERVER_JWT_SECRET_KEY} \
-e SUPER_ADMIN_USERNAME=${SUPER_ADMIN_USERNAME} \
-e SUPER_ADMIN_PASSWORD=${SUPER_ADMIN_PASSWORD} \
--restart unless-stopped \
ghcr.io/amoylab/unla/allinone:latest
```
## Aliyun Image
Devices in China can pull images from Alibaba Cloud registry:
```bash theme={null}
export APISERVER_JWT_SECRET_KEY="changeme-please-generate-a-random-secret"
export SUPER_ADMIN_USERNAME="admin"
export SUPER_ADMIN_PASSWORD="changeme-please-use-a-secure-password"
```
Start using Aliyun image:
```bash theme={null}
docker run -d \
--name unla \
-p 8080:80 \
-p 5234:5234 \
-p 5235:5235 \
-p 5335:5335 \
-p 5236:5236 \
-e ENV=production \
-e TZ=Asia/Shanghai \
-e APISERVER_JWT_SECRET_KEY=${APISERVER_JWT_SECRET_KEY} \
-e SUPER_ADMIN_USERNAME=${SUPER_ADMIN_USERNAME} \
-e SUPER_ADMIN_PASSWORD=${SUPER_ADMIN_PASSWORD} \
--restart unless-stopped \
registry.ap-southeast-1.aliyuncs.com/amoylab/unla-allinone:latest
```
## Access and Configuration
Open [http://localhost:8080/](http://localhost:8080/) in your browser and log in with the configured admin credentials
1. Copy the configuration file: [https://github.com/AmoyLab/Unla/blob/main/configs/proxy-mock-server.yaml](https://github.com/AmoyLab/Unla/blob/main/configs/proxy-mock-server.yaml)
2. Click "Add MCP Server" in the web interface
3. Paste the configuration and save
## Available Endpoints
After configuration, the service will be available at the following endpoints:
* **MCP SSE**: `http://localhost:5235/gateway/user/sse`
* **MCP SSE Message**: `http://localhost:5235/gateway/user/message`
* **MCP Streamable HTTP**: `http://localhost:5235/gateway/user/mcp`
Configure URLs with `/sse` or `/mcp` suffix in your MCP Client to start using the service.
## Testing
You can test the service in two ways:
Use the MCP Chat page in the web interface for testing
Use your own MCP Client (**Recommended**)
## Advanced Configuration (Optional)
If you need more granular configuration control, you can start with mounted configuration files:
```bash theme={null}
mkdir -p unla/{configs,data}
cd unla/
curl -sL https://raw.githubusercontent.com/amoylab/unla/refs/heads/main/configs/apiserver.yaml -o configs/apiserver.yaml
curl -sL https://raw.githubusercontent.com/amoylab/unla/refs/heads/main/configs/mcp-gateway.yaml -o configs/mcp-gateway.yaml
curl -sL https://raw.githubusercontent.com/amoylab/unla/refs/heads/main/.env.example -o .env.allinone
```
```bash theme={null}
docker run -d \
--name unla \
-p 8080:80 \
-p 5234:5234 \
-p 5235:5235 \
-p 5335:5335 \
-p 5236:5236 \
-e ENV=production \
-v $(pwd)/configs:/app/configs \
-v $(pwd)/data:/app/data \
-v $(pwd)/.env.allinone:/app/.env \
--restart unless-stopped \
ghcr.io/amoylab/unla/allinone:latest
```
By mounting configuration files, you can more precisely control the configuration parameters of each service. For detailed configuration instructions, please refer to the [Configuration Documentation](/en/configuration/apiserver).