Model or dataset
bestruirui/octopus avatar
bestruirui/octopus

Octopus: a self-hosted LLM API gateway that rewrites between OpenAI and Anthropic wire formats

One Hub All LLMs For You | 为个人打造的 LLM API 聚合网关

2,625 stars427 forksTypeScriptAGPL-3.0

At a glance

What is it?
Octopus is a Go single-binary gateway with an embedded web panel, aimed at individuals who hold keys for several LLM providers and want one endpoint in front of them. The interesting part is protocol conversion and failover; the awkward part is that it is licensed AGPL-3.0 and ships with admin/admin.
Who is it for?
Adopt Octopus if you run several LLM provider keys for personal or internal use and want a single local endpoint that speaks both the OpenAI Chat and Anthropic formats, with failover and per-request cost logging. Do not adopt it if you need a multi-tenant commercial gateway you intend to resell or embed in a closed product, because AGPL-3.0 is a strong copyleft licence and the README does not describe a tenant isolation model.
Can I use it commercially?
Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
Is it still maintained?
Yes. The repository last received commits 1 day 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 problem Octopus addresses: too many provider keys, too many wire formats

Anyone who pays for more than one LLM provider ends up with the same mess. Each provider has its own base URL, its own authentication header, and increasingly its own request schema. The OpenAI Chat Completions format and the Anthropic Messages format are not interchangeable, and the README lists OpenAI Chat, OpenAI Responses and Anthropic as the three formats Octopus converts between. Client software tends to support one of them. Codex and Codex CLI appear in the repository topics alongside Claude Code and opencode, which suggests the intended user is someone running several agent tools side by side and tired of reconfiguring each one when a key runs out of quota.

The README describes the project as an aggregation service "for individuals", and the feature list reflects that scope. There is no mention of organisations, teams, seats, billing, or tenant separation. That is a meaningful signal about who the software is built for. A single operator, one management panel, one database, one set of upstream credentials.

Channels, groups and the request path through the gateway

The unit of configuration is the channel. A channel is one upstream provider connection, and the README's base URL table is explicit that you supply only the service root: Octopus appends the API version and endpoint path itself based on the channel type. For an OpenAI Chat channel that appended path is /v1/chat/completions. This is a small design decision with real consequences. If a provider changes its path layout, you cannot patch around it by editing the URL in the panel; you wait for a release.

Above channels sit groups, which the screenshots show as a separate management page. The README does not spell out the group semantics in the excerpt available, so the exact relationship between a group and the channels inside it cannot be confirmed from the supplied material. What is stated is that automatic failover switches to an available channel when an upstream channel fails, and that upstream errors are intercepted to keep agent tasks running. Those two claims together describe the core value: the client sees one stable endpoint, and Octopus absorbs the failure underneath.

There is also a real-time end-to-end request visualisation feature, described as watching the complete request path in the frontend from the moment the client sends it. Combined with the logs page and the analytics features (request statistics, token consumption, cost tracking), this means every request is persisted. That is useful for debugging a misbehaving agent, and it also means your prompt contents may be sitting in a SQLite file on disk. The README does not discuss retention or redaction.

Getting it running: Docker, binary, or a Go build with a prebuilt frontend

The fastest path is the published image. The README gives:

docker run -d --name octopus -v /path/to/data:/app/data -p 8080:8080 bestrui/octopus

or, for compose, downloading docker-compose.yml from the repository and running docker compose up -d. The volume mount matters: configuration and database live under /app/data.

Release binaries are also published, run as ./octopus start. Building from source requires Go 1.24.4, Node.js 18+ and pnpm, and the README contains a warning worth reading twice: frontend build artifacts are embedded into the Go binary, so the frontend must be built before the backend starts. The sequence is cd web && pnpm install && pnpm run build, then go run main.go start from the repository root. Development mode runs the Vite dev server on port 5173 against the same Go backend.

Configuration lives in data/config.json, generated on first start. The full example covers server.host, server.port, database.type, database.path and log.level. Every one of those can be overridden by an environment variable using the OCTOPUS_ prefix with the path joined by underscores, so server.port becomes OCTOPUS_SERVER_PORT. There is also OCTOPUS_GITHUB_PAT, described as optional and used for rate limiting when checking the latest version.

The default credentials are admin and admin, and the README carries a security notice telling you to change the password immediately after first login. Treat that as a hard requirement, not a suggestion, because the default listen address is 0.0.0.0.

Database choice is the main operational decision

Octopus supports SQLite, MySQL and PostgreSQL, selected through database.type with sqlite, mysql or postgres, and the connection string goes in database.path. The formats differ per engine: SQLite takes a file path such as data/data.db, MySQL takes user:password@tcp(host:port)/dbname, and PostgreSQL takes a postgresql:// URL, with the README's example using sslmode=disable.

One line in the README deserves attention: MySQL and PostgreSQL require manual database creation, and the application creates the table structure itself. So the schema is managed by the application, not by a migration tool you drive. For a personal deployment on SQLite this is entirely fine and arguably the right default. For anything pointed at a shared PostgreSQL instance, it means you should create a dedicated database rather than letting Octopus write tables into one that other software uses.

The README does not describe a migration path between database engines, and it does not describe what happens to existing tables when the schema changes between releases. Given that v0.13.2, v0.13.3 and v0.13.4 all landed within roughly eight days of each other, release cadence is brisk. Back up the database file before upgrading.

Where Octopus is the wrong tool

The licence is the first constraint. Octopus is AGPL-3.0. That is a strong copyleft licence with a network clause: if you modify it and let users interact with it over a network, the source of your modified version has to be offered to those users. For a personal gateway on your own machine this is a non-issue. For a company that wants to wrap a gateway into a product and keep the modifications private, it is a serious problem. Nothing in the README suggests the authors offer a commercial exception. This is a description of the licence, not legal advice; if your use case is commercial, talk to a lawyer.

Second, the project is explicitly scoped to individuals. There is no mention of per-user API keys, quotas, rate limiting per client, or audit trails separating one user's requests from another's. If you need to hand out keys to a team and see who spent what, the analytics described in the README track requests, tokens and cost, but the material does not describe attribution to individual consumers of the gateway.

Third, the automatic failover and error shielding behaviour is a trade-off, not a pure win. Intercepting upstream errors so that agent tasks continue means the client may not learn that something went wrong upstream. If your workflow depends on distinguishing a genuine model refusal from a provider outage, a gateway that swallows the error is working against you. The README states the behaviour; it does not describe how to configure or disable it, and that configurability is exactly what you would want to check before relying on it.

How this differs from LiteLLM and one-api

The obvious comparison is LiteLLM, a Python proxy that also exposes an OpenAI-compatible endpoint in front of many providers. The difference in approach is packaging and runtime. Octopus compiles the whole service, including the web panel, into a single Go binary, which the README lists as a feature: no external runtime dependencies. LiteLLM is a Python package you deploy with a Python runtime and typically a process manager or container. If your environment already runs Python services, that is not a burden. If you want one file to drop on a small VPS, Octopus has the simpler story.

A second comparison is one-api and its forks, which occupy the same niche of a self-hosted multi-provider gateway with a web panel. The distinguishing detail visible in Octopus is protocol conversion in both directions across three formats (OpenAI Chat, OpenAI Responses, Anthropic) rather than a single normalised format, plus the real-time request path visualisation in the frontend. The README does not describe the conversion fidelity, so whether a tool-calling request written for the Anthropic format survives a round trip through an OpenAI upstream cannot be confirmed from the available material. That is the single most important thing to test yourself, because it is where format-translating gateways usually break.

Upgrade and maintenance cost

The repository shows three releases in the v0.13.x line between 2026-09-02 and 2026-09-10, with the most recent push to master on the same day as v0.13.4. That is a fast-moving project. Fast releases are not automatically a problem, but they do mean you should pin a version rather than tracking latest, and you should read the release notes before each jump. The README does not describe a database migration process, so the safe procedure is to stop the container, copy the data directory (or dump the MySQL or PostgreSQL database), then start the new binary and watch the logs at log.level set to a more verbose value than the default info.

The price sync and model sync features reduce some ongoing maintenance: the README states model pricing updates and channel model lists are synchronised automatically. That is work you would otherwise do by hand every time a provider ships a new model. Against that, the auto-appended endpoint paths mean provider API changes are handled by the maintainer, not by you, which is a maintenance cost you take on in exchange for a simpler configuration file.

One deployment note that the README implies but does not dwell on: the default bind is 0.0.0.0 with default credentials admin/admin. If you expose port 8080 before changing that password, you have published an open gateway to your paid provider keys. Change the password on first login, or bind to 127.0.0.1 and put a reverse proxy in front.

Editorial conclusion

Adopt Octopus if you run several LLM provider keys for personal or internal use and want a single local endpoint that speaks both the OpenAI Chat and Anthropic formats, with failover and per-request cost logging. Do not adopt it if you need a multi-tenant commercial gateway you intend to resell or embed in a closed product, because AGPL-3.0 is a strong copyleft licence and the README does not describe a tenant isolation model. Before trusting it with production keys, verify three things yourself: that the admin password can actually be changed and persisted, that the failover policy behaves the way you expect when an upstream returns a rate-limit error rather than a connection failure, and that the database you point it at is reachable, since the README states MySQL and PostgreSQL require manual database creation before first start.

Official sources

  1. bestruirui/octopus on GitHub
  2. Issues
  3. License: AGPL-3.0
  4. README
  5. Releases
Community notes

Community notes