# 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 Client request example (light) Client request example (dark) Jaeger UI – trace result overview 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 MCP Gateway Hero Light MCP Gateway Hero Dark ## 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 Unla Architecture Light Unla Architecture Hero Dark ## 🚀 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).