Self-hosted service
AmoyLab/Unla avatar
AmoyLab/Unla

Unla (MCP Gateway): YAML-Defined MCP Endpoints for Existing REST APIs

🧩 MCP Gateway - A lightweight gateway service that instantly transforms existing MCP Servers and APIs into MCP servers with zero code changes. Features Docker deployment and management UI, requiring no infrastructure modifications.

2,228 stars184 forksTypeScriptMIT

At a glance

What is it?
Unla is an MIT-licensed Go gateway that turns REST APIs and existing MCP servers into MCP endpoints through YAML configuration and a bundled management UI. The configuration model is the whole product, and it is also where the operational risk sits.
Who is it for?
Adopt Unla if you already run REST services or MCP servers and want them exposed over MCP without writing adapter code, and if you can accept the project's own warning that backward compatibility is not guaranteed between releases. Do not adopt it if you need gRPC or WebSocket conversion, since both are listed as unchecked in the feature list.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 20 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The adapter problem Unla is aimed at

MCP clients speak one protocol. Internal APIs speak another. Bridging the two normally means writing a server per API, mapping each endpoint to a tool schema, and maintaining that code as the underlying API drifts. Unla's claim is that this mapping should be configuration, not code. The README states the project converts existing MCP servers and APIs into MCP-compliant services "all through configuration, with zero code changes." The topic list on the repository (rest-to-mcp, restful-to-mcp, mcp-adapter) confirms that REST-to-MCP is the primary use case, with MCP-to-MCP proxying as the second. The audience is the platform or backend engineer who already has running services and wants them reachable from an MCP client without a build step. That is a narrower audience than "anyone building agents," and Unla is not a framework for authoring new tools. It is a translation and routing layer that sits in front of things that already exist.

What sits between the client and your API

The README describes the data flow in one line: Client, then MCP Gateway, then APIs. The same shape applies to proxying, where the last hop is an existing MCP server instead of a REST endpoint. Unla terminates the MCP connection and exposes it in two transports, SSE and Streamable HTTP, on separate paths under /mcp/user/. Configuration is loaded from YAML and can be hot-reloaded, with sync driven by OS signals, an HTTP call, or Redis PubSub, and persistence backed by Disk, SQLite, PostgreSQL or MySQL. Sessions are described as persistent and recoverable, and the gateway supports multiple tenants and multiple replicas. Two of those features interact: recoverable sessions only mean something if the persistence backend is shared across replicas, and Redis PubSub is the only listed sync mechanism that is inherently cross-instance. If you run a single container with Disk persistence, you get the simple path but not the multi-replica story. The README does not spell out how session state is keyed across replicas, so that combination is worth testing rather than assuming.

Deployment: one container, five ports, three secrets

The quick start is a single Docker image, ghcr.io/amoylab/unla/allinone:latest, with three environment variables set before launch: APISERVER_JWT_SECRET_KEY, SUPER_ADMIN_USERNAME, and SUPER_ADMIN_PASSWORD. The README's example values are literally "changeme-please-generate-a-random-secret" and "changeme-please-use-a-secure-password," which is a clear signal that these are placeholders. The run command maps five ports: 8080 for the web interface, and 5234, 5235, 5335, 5236 for the service endpoints. The documented MCP URLs are http://localhost:5235/mcp/user/sse, http://localhost:5235/mcp/user/message, and http://localhost:5235/mcp/user/mcp. After logging in at http://localhost:8080/, the documented workflow is to open configs/proxy-mock-server.yaml in the repository, click "Add MCP Server" in the UI, paste the configuration, and save. The README recommends testing with your own MCP client rather than the built-in chat page. Note the port spread: four non-web ports are exposed, and the README does not explain what each one carries beyond the 5235 examples, so treat the published mapping as the source of truth for your firewall rules rather than trimming it.

The compatibility warning is the real constraint

The README opens with a note that Unla is under rapid development and that backward compatibility cannot be 100% guaranteed. It then adds that documentation updates may lag behind the code. For a gateway, this matters more than it would for a library. A gateway holds configuration that encodes your API surface, your auth wiring, and your session persistence settings. If the config schema shifts between v0.9.2 and v0.10.0, the upgrade cost lands on every deployment at once. The release history supports the concern: v0.9.1, v0.9.2, and v0.10.0 span roughly seven months, and the jump from 0.9 to 0.10 is a minor-version bump, which is exactly where a project that does not promise compatibility would put a breaking change. There is no version pinning guidance in the README beyond "check version changes carefully when upgrading." Practical implication: pin the image tag rather than using allinone:latest, and read the release notes before moving. The README also points to Discord and Issues as the fallback when documentation lags, which is an honest admission that the docs are not the complete reference.

What is not built yet

The feature list is unusually explicit about gaps, which is useful. gRPC to MCP and WebSocket to MCP are both unchecked. Grouping and aggregating MCP servers is unchecked. So if your estate is gRPC-first, or you wanted one MCP endpoint that fans out across several upstream servers as a single namespace, Unla does not do that today. What is checked: REST-to-MCP conversion, MCP proxying, SSE, Streamable HTTP, responses carrying text, images and audio, persistent sessions, multi-tenancy, hot-reloading, four persistence backends, three sync mechanisms, config version control, OAuth pre-authentication for MCP servers, Docker, and Kubernetes with Helm. OAuth pre-authentication is worth flagging separately: it is listed as a single line with no detail on which flows are supported or where credentials are stored, so if your upstream APIs need OAuth, that is a documentation gap to resolve before committing.

Where a hand-written MCP server still wins

The obvious alternative is writing an MCP server directly, using one of the official SDKs. The difference is where the logic lives. A hand-written server puts tool definitions, argument validation, response shaping, and error mapping in code you control and can unit test. Unla moves all of that into YAML that the gateway interprets at runtime. That trade is good when your API surface is stable and mostly mechanical: a path, a method, a parameter mapping. It is bad when a tool needs conditional behaviour, multi-call orchestration, or response transformation that does not fit the config schema. In those cases you end up either fighting the schema or running a small custom server behind Unla anyway. The other alternative is a general API-to-tool layer that generates tool schemas from an OpenAPI document. Unla's README does not mention OpenAPI ingestion, so the two approaches differ on where the mapping comes from: Unla expects you to write it, while spec-driven tools derive it. If your APIs already have maintained OpenAPI specs, that difference is worth weighing before writing YAML by hand.

Licence and upgrade cost

Unla is MIT licensed. That permits commercial use, modification, and redistribution provided the copyright notice and licence text are retained, and it disclaims warranty. It does not impose copyleft obligations on your own code, which is the practical question for most teams embedding a gateway. This is a description of the licence text, not legal advice; get your own review if the gateway sits in a regulated path. On maintenance: the project is not archived, the last push is recent, and the release cadence is a few releases per year rather than per month. The upgrade cost is dominated by the compatibility caveat plus the persistence choice. If you use Disk persistence, upgrades are a container swap plus a config check. If you use PostgreSQL or MySQL, schema migrations become part of your upgrade runbook, and the README does not describe a migration tool. That is the item to check in the release notes for whichever version you move to, and it is the reason pinning the image tag matters more here than the licence does.

Editorial conclusion

Adopt Unla if you already run REST services or MCP servers and want them exposed over MCP without writing adapter code, and if you can accept the project's own warning that backward compatibility is not guaranteed between releases. Do not adopt it if you need gRPC or WebSocket conversion, since both are listed as unchecked in the feature list. Before rolling it out, verify two things against your own deployment: that the persistence backend you choose (Disk, SQLite, PostgreSQL or MySQL) survives a container restart with sessions intact, and that your config sync mechanism (OS signal, HTTP or Redis PubSub) behaves correctly with more than one replica running.

Official sources

  1. AmoyLab/Unla on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
Community notes

Community notes