unla MCP Gateway

repository·main·Indexed 24 days ago

https://github.com/amoylab/unla

An MCP (Model Context Protocol) Gateway that transforms existing RESTful APIs and MCP servers into MCP-compliant endpoints using configuration-driven proxying. It features a built-in web interface for server management, supports Redis session persistence (v0.2.8+), and provides a CLI via the apiserver and mcp-gateway binaries for configuration and service management.

Tokens
18.4K
Snippets
33
Records
104
Agent score
67%

What's inside unla

  1. What is Unla MCP Gateway?

    main

    Unla is a lightweight, high-availability gateway written in Go. It acts as a middleware that allows individuals and organizations to transform existing MCP (Model Context Protocol) Servers and RESTful APIs into MCP-compliant endpoints via configuration (YAML) without changing a single line of code.

    Core Design Principles

    • Zero Intrusion: Platform-neutral; deploy on bare metal, VMs, ECS, or Kubernetes without infrastructure changes.
    • Configuration Driven: Use YAML to define how APIs are exposed as MCP servers.
    • Lightweight & Efficient: Designed for high performance and high availability.
    • Built-in Management: Includes an out-of-the-box Web UI for easy operation.
  2. Overview of the unla-dashboard template

    main
    The unla-dashboard package uses a React + Tailwind CSS template. It is built on top of Vite, providing Hot Module Replacement (HMR) and standard ESLint rules for development. Tailwind CSS is pre-installed and ready for use within React components.
  3. Core Capabilities of Unla MCP Gateway

    main

    Unla is a lightweight, high-availability gateway designed to transform existing APIs and MCP Servers into MCP-compliant services without code changes.

    Protocol & Proxy Capabilities

    • RESTful API to MCP: Converts Client $\rightarrow$ MCP Gateway $\rightarrow$ APIs.
    • MCP Proxying: Proxies Client $\rightarrow$ MCP Gateway $\rightarrow$ existing MCP Servers.
    • Supported Protocols: MCP SSE and MCP Streamable HTTP.
    • Data Types: Supports returning text, images, and audio results via MCP.

    Session & Multi-Tenancy

    • Session Management: Supports session persistence and recovery.
    • Multi-tenancy: Built-in support for multiple tenants.

    Configuration & Management

    • Hot Reloading: Supports automatic configuration pulling and seamless hot reloading.
    • Persistence: Supports configuration storage via Disk, SQLite, PostgreSQL, or MySQL.
    • Sync Mechanisms: Supports configuration updates via OS Signals, HTTP, or Redis PubSub.
    • Version Control: Includes configuration versioning.

    Security & Deployment

    • Authentication: Supports OAuth authentication in front of MCP Servers.
    • Deployment: Supports Docker, Kubernetes, and Helm.
  4. Understand the MCP Error Response Specification

    main

    Unla follows a dual-layer error reporting mechanism for MCP (Model Context Protocol) over SSE and Streamable HTTP:

    1. HTTP Layer: Uses standard HTTP status codes to indicate if the request was accepted by the server (e.g., 200 OK, 400 Bad Request, 405 Method Not Allowed).
    2. JSON-RPC Layer: Uses a standard JSON-RPC error object within the response body to provide specific details about why a request failed.

    Every request must receive a corresponding response, whether it is a success or an error.

  5. How API Server i18n works

    main

    The MCP-Gateway API Server supports internationalization (i18n) by translating message IDs into localized strings based on the client's language preference. This removes the need for frontend translation maps.

    Workflow:

    1. The API Server uses a middleware to intercept responses.
    2. Messages are identified by UpperCamelCase IDs (e.g., ErrorTenantNotFound, SuccessResourceCreated).
    3. The middleware determines the target language using the following priority:
      • X-Lang request header
      • Accept-Language request header
      • Default language: Chinese (zh)
    4. The middleware translates the message ID into the corresponding language and returns the translated string to the client.

    Supported Languages:

    • Chinese (zh)
    • English (en)
  6. How the internationalization (i18n) error handling system works

    main

    Unla uses a specialized i18n error handling system that allows errors to be created and translated at the point of origin. This avoids the need for middleware to parse and modify response bodies after the fact.

    The Workflow:

    1. Language Detection: The I18nMiddleware extracts and stores the user's language preference from the incoming request.
    2. Error Creation: When an error occurs, you create an I18nError (or use a predefined error) containing a message ID, a default message, and template data.
    3. Response: Use RespondWithError to send an HTTP response that includes the appropriate status code and the translated error message.
    4. Success Messages: For non-error messages (like success notifications), use TranslateMessageGin to translate strings using the current context.
  7. Add new i18n messages and translations

    main

    To add a new message, define it in the corresponding .toml files for each supported language. Use the {{.ParamName}} syntax to allow dynamic parameter injection.

    1. Edit translations/en/messages.toml for English.
    2. Edit translations/zh/messages.toml for Chinese.

    Example Definition:

    # translations/en/messages.toml
    [ErrorCustomValidationFailed]
    other = "Custom validation failed: {{.Reason}}"
    
    # translations/zh/messages.toml
    [ErrorCustomValidationFailed]
    other = "自定义验证失败:{{.Reason}}"

    Usage in Go code:

    return middleware.GetI18nErrorWithData("ErrorCustomValidationFailed", map[string]interface{}{
        "Reason": "Field 'name' cannot be empty",
    })
    # 在 translations/en/messages.toml 中添加
    [ErrorCustomValidationFailed]
    other = "Custom validation failed: {{.Reason}}"
    
    # 在 translations/zh/messages.toml 中添加
    [ErrorCustomValidationFailed]
    other = "自定义验证失败:{{.Reason}}"
  8. Handle errors in SSE mode

    main

    In Server-Sent Events (SSE) mode, error handling follows these rules:

    • Malformed Request: Returns 400 Bad Request. An error JSON body may be attached, but it will not contain an id.
    • Notifications Only: Returns 202 Accepted with no body.
    • Successful Requests: Returns 200 OK with Content-Type: text/event-stream. Errors are sent as SSE data: events containing the standard JSON-RPC error object.
    • Unsupported Connection: Returns 405 Method Not Allowed if the SSE connection is not supported.
    data: {"jsonrpc":"2.0","id":"123","error":{"code":-32601,"message":"Method not found"}}
  9. Create and use internationalized errors in Go

    main

    You can use predefined errors or create custom ones using the i18n package. Errors can be enriched with parameters for template interpolation.

    Creating Errors:

    • Predefined: Use existing error variables and call .WithParam(key, value) to inject data into the translation template.
    • Custom: Use i18n.NewErrorWithCode(messageID, baseError) to define a new error type with a specific ID and base error code.

    Handling Errors in Gin HTTP Handlers: Use the i18n.RespondWithError helper to automatically send the translated error and the correct HTTP status code to the client.

    // Using predefined errors
    return i18n.ErrNotFound.WithParam("ID", id)
    
    // Creating custom errors
    return i18n.NewErrorWithCode("ErrorTenantNotFound", i18n.ErrorNotFound).WithParam("Name", tenantName)
    
    // In a Gin handler
    func GetResource(c *gin.Context) {
        id := c.Param("id")
        resource, err := resourceService.GetByID(id)
        if err != nil {
            // Use helper to send translated error response
            i18n.RespondWithError(c, i18n.ErrNotFound.WithParam("ID", id))
            return
        }
        
        // Translating success messages
        c.JSON(http.StatusOK, gin.H{
            "message": i18n.TranslateMessageGin("SuccessResourceFound", c, nil),
            "data": resource,
        })
    }
  10. Handle errors in Streamable HTTP mode

    main

    In Streamable HTTP mode, error handling depends on the request type:

    • Malformed Request: Returns 400 Bad Request.
    • Notifications Only: Returns 202 Accepted.
    • Successful Requests: Returns 200 OK with a JSON object or array.
      • Single Request Error: The response body is the error object.
      • Batch Request Error: The response body is an array where the specific failed entry contains an error field.
    • SSE Request: If the request includes Accept: text/event-stream, it follows the SSE mode rules.
  11. Configure and Add an MCP Server

    main

    Once Unla is running, you can manage your MCP services via the built-in Web Interface:

    1. Access the UI: Open http://localhost:8080/ in your browser.
    2. Login: Use the SUPER_ADMIN_USERNAME and SUPER_ADMIN_PASSWORD configured during setup.
    3. Add Server: Click "Add MCP Server" in the interface.
    4. Apply Config: Paste your YAML configuration into the provided field and save. This allows you to convert existing RESTful APIs into MCP-compliant endpoints without changing your original code.