Site icon Efficient Coder

AIClient-2-API: The Ultimate Unified API Gateway for Multi-LLM Providers

AIClient-2-API: The Lightweight, OpenAI-Compatible Gateway for Google Gemini, OpenAI, Claude, and Beyond

A step-by-step guide for junior developers, power users, and small teams who want one universal endpoint for every major large-language-model provider.


Table of Contents

  1. Why You Need a Unified API Gateway
  2. What AIClient-2-API Actually Does
  3. Architecture at a Glance (No Jargon)
  4. Installation & First Run in 10 Minutes
  5. Everyday Usage Examples
  6. Advanced Tricks for Teams and Power Users
  7. Troubleshooting & Common Pitfalls
  8. Extending the Gateway for New Providers
  9. Legal Notes & Credits

1. Why You Need a Unified API Gateway

If you have ever built a chatbot, a VS Code extension, or a simple web app that calls a large-language-model (LLM), you know the pain:

  • Different keys, different URLs, different rate limits.
  • Some services block entire regions.
  • Switching from OpenAI to Claude means rewriting request code.

AIClient-2-API removes all of that friction. You run one small Node.js server on your laptop, in Docker, or on a VPS. Every client—LobeChat, NextChat, a Python script, or even curl—points to the same local address. Behind the scenes the gateway silently translates each request to the right upstream provider and returns the response in perfect OpenAI format.

Benefits you will notice immediately:

Pain Point Today After AIClient-2-API
Three API keys in three config files One key, one URL
Region blocks for Google Gemini Gateway handles OAuth flow for you
Claude 3 Opus costs money Kiro mode gives you Claude Sonnet 4 for free (subject to Kiro’s terms)
Switching providers means code changes Change one line in config.json
No local logs Full prompt/response logs to console or file

2. What AIClient-2-API Actually Does

In one sentence: It is a tiny reverse proxy that speaks OpenAI on the outside and Gemini, OpenAI, Claude, or Kiro on the inside.

External Interface Internal Translation
/v1/chat/completions Converted to Gemini, OpenAI, Claude, or Kiro request
/v1/models Lists every model the provider offers
/health Returns uptime and current config
/v1beta/* Native Gemini routes (optional)
/v1/messages Native Claude routes (optional)

You pick the upstream provider at startup:

  • gemini-cli-oauth – Uses the Google Gemini CLI behind the scenes; automatic OAuth token refresh
  • openai-custom – Your own OpenAI key or any OpenAI-compatible endpoint
  • claude-custom – Your own Anthropic key
  • claude-kiro-oauth – Free Claude access via the Kiro ecosystem

3. Architecture at a Glance (No Jargon)

You do not need to understand the code to use the gateway, but a high-level picture helps when you debug or extend it.

┌──────────────┐        ┌──────────────┐        ┌──────────────┐
│   Your App   │───────▶│   Gateway    │───────▶│ Real Service │
│ (OpenAI fmt) │◀───────│ (Translator) │◀───────│(Gemini,etc.) │
└──────────────┘        └──────────────┘        └──────────────┘

Key files you may open one day:

File Purpose
src/api-server.js Starts the HTTP server, loads config
src/adapter.js Chooses the correct provider adapter
src/convert.js Converts request/response formats
config.json Where you set keys, ports, and model choices

The project uses classic design patterns—Adapter, Strategy, Factory—so adding a new provider is roughly:

  1. Create a new folder under src/.
  2. Implement two tiny JavaScript classes (adapter + strategy).
  3. Register the classes in adapter.js.

That is it. No core logic changes required.


4. Installation & First Run in 10 Minutes

4.1 Prerequisites

  • Node.js 20 or newer (check with node -v)
  • Git (or download the ZIP from GitHub)

4.2 Clone and Install

git clone https://github.com/your-org/AIClient-2-API.git
cd AIClient-2-API
npm install      # installs ~10 lightweight dependencies

4.3 Create Your First Config

Copy-paste the snippet below into a new file named config.json. Replace the placeholder strings with your real keys or leave them empty for the OAuth modes.

{
  "REQUIRED_API_KEY": "my-secret-123",
  "HOST": "0.0.0.0",
  "SERVER_PORT": 3000,
  "MODEL_PROVIDER": "gemini-cli-oauth",
  "OPENAI_API_KEY": "",
  "OPENAI_BASE_URL": "https://api.openai.com/v1",
  "CLAUDE_API_KEY": "",
  "CLAUDE_BASE_URL": "https://api.anthropic.com",
  "PROJECT_ID": "gcp-project-123",
  "PROMPT_LOG_MODE": "console"
}

Quick field guide:

Key Beginner Explanation
REQUIRED_API_KEY A simple password so strangers cannot use your server
HOST Use 0.0.0.0 if you plan to call the gateway from another device
MODEL_PROVIDER One of four strings: "gemini-cli-oauth", "openai-custom", "claude-custom", "claude-kiro-oauth"
PROMPT_LOG_MODE "console" shows logs in your terminal; "file" writes to disk

4.4 First Run

node src/api-server.js

You should see:

AIClient-2-API listening on http://0.0.0.0:3000
Provider set to: gemini-cli-oauth
Prompt logs → console

If you chose Gemini CLI mode, a browser window will pop up asking for your Google account. Grant the permission once; the gateway will refresh tokens automatically.


5. Everyday Usage Examples

5.1 Health Check

curl http://localhost:3000/health

Response:

{"status":"ok","provider":"gemini-cli-oauth","uptime":"12s"}

5.2 List Models

curl http://localhost:3000/v1/models \
  -H "Authorization: Bearer my-secret-123"

You will get a JSON array that looks exactly like OpenAI’s /v1/models answer, regardless of the upstream provider.

5.3 Simple Chat (No Streaming)

curl http://localhost:3000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer my-secret-123" \
  -d '{
    "model": "gemini-2.5-flash",
    "messages": [
      {"role": "user", "content": "Explain quantum tunneling like I am 12."}
    ]
  }'

5.4 Chat with Streaming

Add "stream": true and use -N so curl displays each token as it arrives:

curl -N http://localhost:3000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer my-secret-123" \
  -d '{
    "model": "claude-3-opus-20240229",
    "messages": [{"role": "user", "content": "Write a haiku about debugging."}],
    "stream": true
  }'

5.5 Vision (Image + Text)

Images must be base64-encoded data URLs. The gateway forwards them transparently.

curl http://localhost:3000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer my-secret-123" \
  -d '{
    "model": "gemini-2.5-flash",
    "messages": [{
      "role": "user",
      "content": [
        {"type": "text", "text": "What is this logo?"},
        {"type": "image_url", "image_url": {"url": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..."}}
      ]
    }]
  }'

5.6 Switching Providers on the Fly

You have two ways:

  1. Restart with a new provider:

    node src/api-server.js --model-provider claude-custom --claude-api-key sk-ant-xxx
    
  2. Use path-based routing (no restart):

    # Gemini
    curl http://localhost:3000/gemini-cli-oauth/v1/chat/completions ...
    
    # Claude
    curl http://localhost:3000/claude-custom/v1/chat/completions ...
    

6. Advanced Tricks for Teams and Power Users

6.1 Persistent Logging for Audits

Set in config.json:

"PROMPT_LOG_MODE": "file",
"PROMPT_LOG_BASE_NAME": "audit"

Every request and response will be written to audit-YYYY-MM-DD.log with millisecond timestamps. The file is plain text—easy to grep, zip, or feed into a data pipeline.

6.2 Dynamic System Prompts

Create input_system_prompt.txt:

You are a helpful assistant. Always cite your sources.

Then add to config.json:

"SYSTEM_PROMPT_FILE_PATH": "input_system_prompt.txt",
"SYSTEM_PROMPT_MODE": "append"

Result: the gateway silently appends your rule to every chat, even if the client did not send a system message.

6.3 Docker One-Liner

A ready-made Dockerfile is included. Build and run:

docker build -t ai-gateway .
docker run -p 3000:3000 \
  -v $(pwd)/config.json:/app/config.json \
  ai-gateway

Mount your OAuth credential files the same way if you use Gemini CLI or Kiro modes.

6.4 Running Multiple Instances

Because the gateway is stateless, you can start several copies on different ports:

# Terminal 1
node src/api-server.js --port 3001 --model-provider openai-custom

# Terminal 2
node src/api-server.js --port 3002 --model-provider claude-custom

Then load-balance with nginx or Caddy for zero-downtime fail-over.


7. Troubleshooting & Common Pitfalls

Symptom Quick Fix
401 Unauthorized Check that the client sends Authorization: Bearer <REQUIRED_API_KEY>
ENOTFOUND during OAuth Set HTTPS_PROXY and HTTP_PROXY environment variables if you are behind a corporate firewall
Empty model list Verify the upstream key has quota; Gemini CLI mode needs a successful first login
Very slow responses Increase REQUEST_MAX_RETRIES and REQUEST_BASE_DELAY, or check your network proxy
Docker cannot see credential files Use absolute paths in -v mounts; on Windows use %cd% instead of $(pwd)

8. Extending the Gateway for New Providers

Suppose you want to add Mistral AI:

  1. Create src/mistral/.

  2. Copy src/openai/openai-adapter.js to src/mistral/mistral-adapter.js and change the base URL.

  3. Copy src/openai/openai-strategy.js to src/mistral/mistral-strategy.js and tweak the request/response shape if Mistral differs.

  4. Register the adapter in src/adapter.js with one line:

    case 'mistral-custom':
      return new MistralAdapter(config);
    
  5. Re-start the server with --model-provider mistral-custom.

That is literally all. The test suite will automatically pick up the new provider if you follow the same folder conventions.


9. Legal Notes & Credits

  • License: GNU General Public License v3 (GPLv3). You may use, modify, and redistribute the code freely, but any derivative work must also be open-source under the same license.
  • Upstream Terms: Your use of Google Gemini, OpenAI, Claude, or Kiro remains governed by their respective terms of service. The gateway does not store or retransmit data beyond your own logs.
  • Credits: The project is inspired by the official Google Gemini CLI and borrows small portions of early Cline code. We thank Google and the Cline authors for their excellent groundwork.

Happy building—and may your tokens always stream smoothly.

Exit mobile version