# CrossLink: an OpenAI and Anthropic compatible LLM gateway in Go

> CrossLink proxies OpenAI, Anthropic, Azure, DeepSeek, Qwen and Ollama behind one endpoint, with streaming protocol translation, error-classified failover and an MCP gateway. Here is how it builds, where it is thin, and who should skip it.

**HotRiceNoodles/CrossLink** — Unified large model proxy gateway, providing load balancing, fault transfer, current limiting, budget management, content auditing, caching, and MCP gateway capabilities.

- Repository: https://github.com/HotRiceNoodles/CrossLink
- Stars: 506 · Forks: 36
- Language: Go
- License: Apache-2.0
- Published: 2026-09-20 · Updated: 2026-09-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/hotricenoodles-crosslink

## The multi-provider adapter problem CrossLink targets

If your application talks to more than one large model provider, you have written the same adapter several times. OpenAI, Anthropic, Azure, DeepSeek, Qwen, Moonshot and Ollama each differ in request shape, auth mechanism and streaming event format. The README states the goal plainly: CrossLink is a "universal adapter" so your code talks to a single API in either OpenAI or Anthropic format, and requests are routed onward.

The intended user is a platform or backend team that has outgrown a single provider but does not want provider-specific code in every service. CrossLink is written in Go, licensed Apache-2.0, and its module path is github.com/crosslink. The README describes a split edition model: the Community edition ships 47 actions including MCP, RBAC, routing stats, error rules, guardrail CRUD, the interactive playground, prompt templates and scoped PATs, while secrets, guardrail alerts, debug replay, DataLens, agent shielding, multi-org, audit and the budget management console sit in Pro and Enterprise. That is the first thing to check against your requirements, because several control-plane features are not in the open build.

## Routing, protocol translation and failover mechanics

Requests enter through two endpoints: /v1/chat/completions in OpenAI format and /v1/messages in Anthropic format. The README says translation between OpenAI, Anthropic and the OpenAI Responses API is handled by a state machine rather than request-level rewrites, and that it covers streaming SSE, thinking blocks, partial-JSON tool arguments and token counting mid-stream. That distinction matters: a state machine can convert a stream event by event, which a rewrite of the request body cannot do.

Routing offers six strategies: weighted random, round-robin, least latency, least cost, least busy, and canary deployment. Failover is not a blind retry loop. Errors are classified as persistent (quota or billing, one strike and a long cooldown) or transient (rate limit, threshold-based), with the rule table stored in the database. When a flaky provider recovers, half-open single-flight probing is used to avoid a stampede of simultaneous retries.

Two mechanisms make the routing visible. Every response carries x-crosslink-fallback-model and x-crosslink-fallback-count headers, and a routing-stats API reports configured-versus-actual traffic distribution, deviation, error rate and latency per provider. Per-(provider, model) concurrency and RPM limits are enforced through Redis Lua with a TTL heartbeat, so a crashed process cannot leave a provider marked busy forever. The go.mod file confirms the dependency set behind this: go-redis/v9, gin, gorm with MySQL, Postgres and SQLite drivers, golang-migrate, and the gmsm library for SM2/SM3/SM4.

## Building CrossLink from source and sending a first request

There is no published binary or package in the repository. The Makefile is the entry point, and it builds the server from cmd/server. The README badge states Go 1.22+, while go.mod declares go 1.26.2, so use a toolchain that satisfies the module file.

Clone the repository and build the binary:

```bash
git clone https://github.com/HotRiceNoodles/CrossLink.git
cd CrossLink
make build
```

The build target runs go build -o bin/crosslink ./cmd/server, so the result is bin/crosslink. For a quick local run without producing a binary, the Makefile also offers make run, which executes go run ./cmd/server.

Configuration is read with viper, and the repository has a configs/ directory plus a migrations/ directory at the top level. The repository does not reproduce the config file contents, so read configs/ and the deployment documentation under docs/ before starting the server, and apply the migrations for your database engine.

Once the server is up, point an existing OpenAI-format client at the gateway by changing the base URL only. The README gives the OpenAI-compatible path as /v1/chat/completions.

After the first call, inspect the response headers for x-crosslink-fallback-model and x-crosslink-fallback-count. If they are present and the count is zero, the request was served by the primary route. From there, add providers and failover chains, and check the routing-distribution API to confirm the configured weights match what is actually being served. For test runs, the Makefile separates unit from integration work: make test runs go test ./..., while make test-integration brings up deployments/docker-compose.test.yaml, runs the dialect tests with the integration build tag, then tears the stack down.

## Where CrossLink is the wrong tool

The gateway is stateful infrastructure. Redis is required for response caching, the per-(provider, model) dispatch counters, and the Lua-based rate limiting, so a deployment without Redis loses more than a cache. If you call exactly one provider and never intend to add a second, you are paying for a translation layer, a database, and a Redis instance to solve a problem you do not have.

The edition split is the sharper limitation. Budget management is described as enforced at the gateway with automatic circuit breaking, but the budget management console is listed under Enterprise. Guardrail alerts, debug replay, DataLens, secrets and agent shielding are Pro. Multi-org and audit are Enterprise. So a team that needs a budget UI or an audit trail will not get it from the Apache-2.0 build, and the README does not describe how those tiers are obtained.

The documentation is also silent on several operational questions. There is no documented rollback procedure, no stated default listen port, no published container image, and no benchmark or load figure. The MCP gateway is described as having encrypted credentials and allow/deny lists scoped by key, team or role, but the README does not explain where those credentials are stored or how they are rotated. Treat the first production rollout as something you validate yourself against the configs/ and migrations/ directories rather than something the documentation walks you through.

## How CrossLink differs from LiteLLM and a plain reverse proxy

LiteLLM is the closest comparison in purpose: a Python proxy that exposes an OpenAI-compatible surface over many providers. The difference in approach is the streaming layer. CrossLink's README claims a bidirectional state machine for OpenAI, Anthropic and the Responses API, including thinking blocks and partial-JSON tool arguments, rather than request-level rewrites. If you route Anthropic-format traffic through a proxy that only rewrites requests, streaming tool calls are where you will notice it. The second difference is the failover model: CrossLink stores error classification rules in a database table and distinguishes persistent from transient failures, instead of retrying uniformly.

Against nginx or Envoy with a rewrite rule, the gap is larger. A reverse proxy balances and retries but does not translate protocols, does not classify provider errors, and does not expose routing distribution. CrossLink also bundles an MCP gateway with per-tool RBAC and a guardrail plugin registry with a RegisterEngine hook, actions of block, log or mask, and per-model configuration. Those are application-level concerns that a generic proxy has no concept of. The trade is that you now run a Go service with a database and Redis, where a proxy config file was previously enough.

## Licence, maintenance and upgrade cost

CrossLink is Apache-2.0, and the LICENSE file is at the repository root. That covers the code in the repository; it says nothing about the Pro and Enterprise features, which the README presents as separate editions without describing their licensing terms. If your plan depends on secrets, guardrail alerts, debug replay, DataLens or the budget console, resolve that question before committing to the open build.

The last push to the default branch was on 2026-09-13, and the repository is not archived. The only release listed is v0.1.0, tagged on 2026-06-12 as an initial release. A single release tag with a version prefix of 0.1.0 is worth weighing: the README documents a broad feature surface, and the upgrade path between future minor versions is not described in the repository.

Upgrade cost is concentrated in the database. golang-migrate is a direct dependency and there is a migrations/ directory, so schema changes ship as migrations you must apply. The Makefile also enforces generated artifacts: make spec-bundle regenerates internal/apidoc/openapi.bundled.json from docs/api, and make spec-check fails the build if the committed bundle drifts from the modular source. If you build from source rather than consuming a binary, run these targets as part of your own pipeline. The Python SDK is generated from the bundled spec through openapi-generator, which the Makefile notes requires Java 8+ and npx locally, or the openapitools/openapi-generator-cli container image in CI.

## Conclusion

Adopt CrossLink if you already run several LLM providers and want one OpenAI or Anthropic compatible endpoint with failover chains, Redis-backed caching and an MCP gateway with per-tool RBAC. Skip it if you call a single provider, if you cannot run Redis, or if you need the Pro and Enterprise features (secrets, guardrail alerts, debug replay, DataLens, multi-org audit, the budget console) on the Apache-2.0 build alone. Verify first that the configs/ directory contains a working config for your database and Redis, that the migrations/ directory applies cleanly against your engine, and that the routing-distribution API shows the configured-vs-actual weights you expect before you move production traffic.

## FAQ

### What is CrossLink and what does it do?

CrossLink is a unified large model proxy gateway written in Go. It exposes OpenAI and Anthropic compatible endpoints and routes requests to OpenAI, Anthropic, Azure OpenAI, DeepSeek, Qwen, Moonshot, Ollama or any OpenAI-compatible provider, adding failover, caching, rate limiting, guardrails and an MCP gateway.

### How do I install CrossLink?

There is no published binary in the repository. Clone the repository and run make build, which executes go build -o bin/crosslink ./cmd/server, or use make run to start it directly with go run ./cmd/server. Configuration lives in the configs/ directory and migrations are applied from migrations/.

### Does CrossLink need Redis?

Yes for the features that depend on it. The README describes Redis-based response caching, per-(provider, model) concurrency and RPM limits enforced through Redis Lua with a TTL heartbeat, and Redis-backed rate limiting. go.mod lists github.com/redis/go-redis/v9 as a direct dependency.

### Is CrossLink free to use?

The Community edition is Apache-2.0, with the LICENSE file at the repository root. The README lists secrets, guardrail alerts, debug replay, DataLens and agent shielding under Pro, and multi-org, audit and the budget management console under Enterprise, but it does not describe the terms for those editions.

### How can I tell which provider actually served a request?

Every response carries x-crosslink-fallback-model and x-crosslink-fallback-count headers, according to the README. There is also a routing-stats API that reports configured-versus-actual traffic distribution, deviation, error rate and latency per provider.

## Sources

- [HotRiceNoodles/CrossLink on GitHub](https://github.com/HotRiceNoodles/CrossLink)
- [Issues](https://github.com/HotRiceNoodles/CrossLink/issues)
- [License: Apache-2.0](https://github.com/HotRiceNoodles/CrossLink/blob/main/LICENSE)
- [README](https://github.com/HotRiceNoodles/CrossLink/blob/main/README.md)
- [Releases](https://github.com/HotRiceNoodles/CrossLink/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/hotricenoodles-crosslink
