Local AI Gateway — expose locally authenticated AI tools as OpenAI-compatible and Anthropic-compatible HTTP APIs.
Runs on 127.0.0.1 only. Credentials are read from existing local config files — no tokens are extracted, forwarded, or stored.
git clone https://github.com/hotea/LocalAI-Bridge.git
cd LocalAI-Bridge
npm install
npm run devOr one-click install:
curl -fsSL https://raw.githubusercontent.com/hotea/LocalAI-Bridge/main/install.sh | bashThe server starts at http://127.0.0.1:6271.
| Provider | Method | Auth |
|---|---|---|
| Claude Code | Subprocess (claude CLI) |
Auto-detect via claude --version |
| GitHub Copilot | HTTP API (api.githubcopilot.com) |
Auto-scan ~/.config/github-copilot/ |
| Kiro | HTTP API (AWS CodeWhisperer) | Auto-scan ~/.aws/sso/cache/ |
| Antigravity | HTTP API (Google Cloud AI) | Auto-scan Antigravity IDE local data, or config.json |
Prerequisites: Node.js >= 20 and at least one provider configured locally.
| Method | Path | Description |
|---|---|---|
| GET | /health |
Provider health status |
| GET | /v1/models |
List available models |
| POST | /v1/chat/completions |
OpenAI chat completions (streaming & non-streaming) |
| POST | /v1/messages |
Anthropic Messages API (streaming & non-streaming) |
# Health check
curl http://127.0.0.1:6271/health
# List all available models
curl http://127.0.0.1:6271/v1/modelsNon-streaming:
curl -X POST http://127.0.0.1:6271/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "claude-code:sonnet",
"messages": [{"role": "user", "content": "Say hello in one sentence"}]
}'Streaming:
curl -X POST http://127.0.0.1:6271/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "claude-code:opus",
"messages": [{"role": "user", "content": "Write a Python function to reverse a string"}],
"stream": true
}'Available models: claude-code:sonnet, claude-code:opus, claude-code:haiku
Non-streaming:
curl -X POST http://127.0.0.1:6271/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "copilot:claude-sonnet-4",
"messages": [{"role": "user", "content": "Explain closures in JavaScript"}]
}'Streaming:
curl -X POST http://127.0.0.1:6271/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "copilot:gpt-4o",
"messages": [{"role": "user", "content": "Write a binary search algorithm in Go"}],
"stream": true
}'With system prompt:
curl -X POST http://127.0.0.1:6271/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "copilot:claude-sonnet-4",
"messages": [
{"role": "system", "content": "You are a helpful coding assistant. Reply concisely."},
{"role": "user", "content": "How do I reverse a linked list?"}
]
}'Available models: copilot:claude-sonnet-4, copilot:claude-3.7-sonnet, copilot:gpt-4o, copilot:gpt-4.1, copilot:o4-mini, copilot:gemini-2.0-flash, copilot:gemini-2.5-pro
Non-streaming:
curl -X POST http://127.0.0.1:6271/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "kiro:claude-sonnet-4",
"messages": [{"role": "user", "content": "What is the difference between TCP and UDP?"}]
}'Streaming:
curl -X POST http://127.0.0.1:6271/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "kiro:claude-sonnet-4.5",
"messages": [{"role": "user", "content": "Write a Rust function that finds the longest common subsequence"}],
"stream": true
}'Multi-turn conversation:
curl -X POST http://127.0.0.1:6271/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "kiro:claude-sonnet-4",
"messages": [
{"role": "user", "content": "What is a binary tree?"},
{"role": "assistant", "content": "A binary tree is a tree data structure where each node has at most two children."},
{"role": "user", "content": "How do I traverse one in-order?"}
]
}'Available models: kiro:claude-sonnet-4, kiro:claude-sonnet-4.5, kiro:claude-3-7-sonnet, kiro:claude-haiku-4.5
Non-streaming:
curl -X POST http://127.0.0.1:6271/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "antigravity:claude-sonnet-4-5",
"messages": [{"role": "user", "content": "Explain quantum computing in simple terms"}]
}'Streaming:
curl -X POST http://127.0.0.1:6271/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "antigravity:gemini-3-pro-high",
"messages": [{"role": "user", "content": "Write a TypeScript function to debounce API calls"}],
"stream": true
}'With system prompt:
curl -X POST http://127.0.0.1:6271/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "antigravity:claude-opus-4-6-thinking",
"messages": [
{"role": "system", "content": "You are an expert software architect."},
{"role": "user", "content": "Design a scalable microservices architecture"}
]
}'Available models: antigravity:claude-sonnet-4-5, antigravity:claude-sonnet-4-5-thinking, antigravity:claude-opus-4-5-thinking, antigravity:claude-opus-4-6-thinking, antigravity:gemini-3-pro-high, antigravity:gemini-3-pro-low, antigravity:gemini-3-flash
All providers support the Anthropic Messages API format:
curl -X POST http://127.0.0.1:6271/v1/messages \
-H "Content-Type: application/json" \
-H "x-api-key: not-needed" \
-H "anthropic-version: 2023-06-01" \
-d '{
"model": "copilot:claude-sonnet-4",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "Hello"}]
}'Streaming:
curl -X POST http://127.0.0.1:6271/v1/messages \
-H "Content-Type: application/json" \
-H "x-api-key: not-needed" \
-H "anthropic-version: 2023-06-01" \
-d '{
"model": "antigravity:claude-sonnet-4-5",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "Hello"}],
"stream": true
}'Python:
from openai import OpenAI
client = OpenAI(base_url="http://127.0.0.1:6271/v1", api_key="not-needed")
# Non-streaming
response = client.chat.completions.create(
model="copilot:claude-sonnet-4",
messages=[{"role": "user", "content": "Hello!"}],
)
print(response.choices[0].message.content)
# Streaming
stream = client.chat.completions.create(
model="copilot:claude-sonnet-4",
messages=[{"role": "user", "content": "Hello!"}],
stream=True,
)
for chunk in stream:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="")Node.js:
import OpenAI from "openai";
const client = new OpenAI({ baseURL: "http://127.0.0.1:6271/v1", apiKey: "not-needed" });
const stream = await client.chat.completions.create({
model: "copilot:gpt-4o",
messages: [{ role: "user", content: "Hello!" }],
stream: true,
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}Python:
from anthropic import Anthropic
client = Anthropic(base_url="http://127.0.0.1:6271", api_key="not-needed")
message = client.messages.create(
model="copilot:claude-sonnet-4",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello!"}],
)
print(message.content[0].text)Node.js:
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({ baseURL: "http://127.0.0.1:6271", apiKey: "not-needed" });
const message = await client.messages.create({
model: "copilot:claude-sonnet-4",
max_tokens: 1024,
messages: [{ role: "user", content: "Hello!" }],
});
console.log(message.content[0].text);Use the provider:model format:
| Provider | Example Models |
|---|---|
claude-code |
claude-code:sonnet, claude-code:opus, claude-code:haiku |
copilot |
copilot:claude-sonnet-4, copilot:gpt-4o, copilot:gemini-2.5-pro |
kiro |
kiro:claude-sonnet-4, kiro:claude-sonnet-4.5 |
antigravity |
antigravity:claude-sonnet-4-5, antigravity:gemini-3-pro-high |
Built-in aliases: gpt-4 / gpt-4o → copilot:gpt-4o, gpt-4o-mini / gpt-3.5-turbo → copilot:o4-mini
If the Antigravity IDE is installed locally, credentials are auto-scanned from its data directory — no configuration needed.
If auto-scan doesn't find credentials, you can provide them manually:
Option 1 — OAuth login flow:
- Start the server:
npm run dev curl -X POST http://127.0.0.1:6271/auth/antigravity/login— returns a Google OAuth URL- Open the URL in a browser, sign in with your Google account
- After redirect, the refresh token is saved to
config.jsonautomatically - Restart the server
Option 2 — Manual configuration:
Add to config.json:
{
"providers": {
"antigravity": {
"refreshToken": "1//your-refresh-token-here"
}
}
}Copy config.default.json to config.json to override settings (gitignored):
cp config.default.json config.jsonEnvironment variable overrides:
| Variable | Description |
|---|---|
LOCALAI_HOST |
Bind address (default: 127.0.0.1) |
LOCALAI_PORT |
Port (default: 6271) |
LOCALAI_CLAUDE_BINARY |
Path to claude CLI binary |
- Server binds to
127.0.0.1only (hostname binding + middleware double-check) - No tokens are extracted, forwarded, or stored by this service
- Copilot: reads the local OAuth token and exchanges it for a short-lived session token via GitHub's official API
- Kiro: reads the local access/refresh token and refreshes it via the official Kiro/AWS auth endpoints
- Claude Code: calls the CLI as a subprocess — inherits the user's existing authentication
- Antigravity: uses a user-provided Google OAuth refresh token, auto-refreshes access tokens
spawn()with argument arrays (no shell injection)
MIT
本地 AI 网关 — 将本地已认证的 AI 工具暴露为 OpenAI 兼容 和 Anthropic 兼容 的 HTTP API。
仅在 127.0.0.1 运行。凭据从现有本地配置文件中读取,不会提取、转发或存储令牌。
git clone https://github.com/hotea/LocalAI-Bridge.git
cd LocalAI-Bridge
npm install
npm run dev或一键安装:
curl -fsSL https://raw.githubusercontent.com/hotea/LocalAI-Bridge/main/install.sh | bash服务启动于 http://127.0.0.1:6271。
| 提供商 | 方式 | 认证 |
|---|---|---|
| Claude Code | 子进程(claude CLI) |
自动检测 claude --version |
| GitHub Copilot | HTTP API (api.githubcopilot.com) |
自动扫描 ~/.config/github-copilot/ |
| Kiro | HTTP API (AWS CodeWhisperer) | 自动扫描 ~/.aws/sso/cache/ |
| Antigravity | HTTP API (Google Cloud AI) | 自动扫描 Antigravity IDE 本地数据,或 config.json |
前置要求: Node.js >= 20,且至少配置一个本地提供商。
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /health |
提供商健康状态 |
| GET | /v1/models |
列出所有可用模型 |
| POST | /v1/chat/completions |
OpenAI 格式聊天补全(支持流式) |
| POST | /v1/messages |
Anthropic Messages API(支持流式) |
# 健康检查
curl http://127.0.0.1:6271/health
# 列出所有可用模型
curl http://127.0.0.1:6271/v1/models非流式:
curl -X POST http://127.0.0.1:6271/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "claude-code:sonnet",
"messages": [{"role": "user", "content": "用一句话说你好"}]
}'流式:
curl -X POST http://127.0.0.1:6271/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "claude-code:opus",
"messages": [{"role": "user", "content": "写一个 Python 函数反转字符串"}],
"stream": true
}'可用模型:claude-code:sonnet, claude-code:opus, claude-code:haiku
非流式:
curl -X POST http://127.0.0.1:6271/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "copilot:claude-sonnet-4",
"messages": [{"role": "user", "content": "解释 JavaScript 中的闭包"}]
}'流式:
curl -X POST http://127.0.0.1:6271/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "copilot:gpt-4o",
"messages": [{"role": "user", "content": "用 Go 写一个二分查找算法"}],
"stream": true
}'带系统提示词:
curl -X POST http://127.0.0.1:6271/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "copilot:claude-sonnet-4",
"messages": [
{"role": "system", "content": "你是一个编程助手,回答要简洁。"},
{"role": "user", "content": "如何反转链表?"}
]
}'可用模型:copilot:claude-sonnet-4, copilot:claude-3.7-sonnet, copilot:gpt-4o, copilot:gpt-4.1, copilot:o4-mini, copilot:gemini-2.0-flash, copilot:gemini-2.5-pro
非流式:
curl -X POST http://127.0.0.1:6271/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "kiro:claude-sonnet-4",
"messages": [{"role": "user", "content": "TCP 和 UDP 有什么区别?"}]
}'流式:
curl -X POST http://127.0.0.1:6271/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "kiro:claude-sonnet-4.5",
"messages": [{"role": "user", "content": "用 Rust 写一个函数找最长公共子序列"}],
"stream": true
}'多轮对话:
curl -X POST http://127.0.0.1:6271/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "kiro:claude-sonnet-4",
"messages": [
{"role": "user", "content": "什么是二叉树?"},
{"role": "assistant", "content": "二叉树是一种树状数据结构,每个节点最多有两个子节点。"},
{"role": "user", "content": "如何中序遍历?"}
]
}'可用模型:kiro:claude-sonnet-4, kiro:claude-sonnet-4.5, kiro:claude-3-7-sonnet, kiro:claude-haiku-4.5
非流式:
curl -X POST http://127.0.0.1:6271/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "antigravity:claude-sonnet-4-5",
"messages": [{"role": "user", "content": "用简单的语言解释量子计算"}]
}'流式:
curl -X POST http://127.0.0.1:6271/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "antigravity:gemini-3-pro-high",
"messages": [{"role": "user", "content": "写一个 TypeScript 函数实现防抖"}],
"stream": true
}'带系统提示词:
curl -X POST http://127.0.0.1:6271/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "antigravity:claude-opus-4-6-thinking",
"messages": [
{"role": "system", "content": "你是一个资深软件架构师。"},
{"role": "user", "content": "设计一个可扩展的微服务架构"}
]
}'可用模型:antigravity:claude-sonnet-4-5, antigravity:claude-sonnet-4-5-thinking, antigravity:claude-opus-4-5-thinking, antigravity:claude-opus-4-6-thinking, antigravity:gemini-3-pro-high, antigravity:gemini-3-pro-low, antigravity:gemini-3-flash
所有供应商都支持 Anthropic Messages API 格式:
curl -X POST http://127.0.0.1:6271/v1/messages \
-H "Content-Type: application/json" \
-H "x-api-key: not-needed" \
-H "anthropic-version: 2023-06-01" \
-d '{
"model": "copilot:claude-sonnet-4",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "你好"}]
}'流式:
curl -X POST http://127.0.0.1:6271/v1/messages \
-H "Content-Type: application/json" \
-H "x-api-key: not-needed" \
-H "anthropic-version: 2023-06-01" \
-d '{
"model": "antigravity:claude-sonnet-4-5",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "你好"}],
"stream": true
}'使用 provider:model 格式:
| 供应商 | 示例模型 |
|---|---|
claude-code |
claude-code:sonnet, claude-code:opus, claude-code:haiku |
copilot |
copilot:claude-sonnet-4, copilot:gpt-4o, copilot:gemini-2.5-pro |
kiro |
kiro:claude-sonnet-4, kiro:claude-sonnet-4.5 |
antigravity |
antigravity:claude-sonnet-4-5, antigravity:gemini-3-pro-high |
内置别名:gpt-4 / gpt-4o → copilot:gpt-4o, gpt-4o-mini / gpt-3.5-turbo → copilot:o4-mini
如果本地已安装 Antigravity IDE,凭据会自动从其数据目录扫描,无需额外配置。
如果自动扫描未找到凭据,可以手动配置:
方式一 — OAuth 登录流程:
- 启动服务:
npm run dev curl -X POST http://127.0.0.1:6271/auth/antigravity/login— 返回 Google OAuth 链接- 在浏览器中打开链接并登录
- 重定向后刷新令牌自动保存到
config.json - 重启服务
方式二 — 手动配置:
在 config.json 中添加:
{
"providers": {
"antigravity": {
"refreshToken": "1//your-refresh-token-here"
}
}
}复制 config.default.json 为 config.json(已加入 gitignore)进行自定义:
cp config.default.json config.json环境变量覆盖:
| 变量 | 说明 |
|---|---|
LOCALAI_HOST |
绑定地址(默认 127.0.0.1) |
LOCALAI_PORT |
端口(默认 6271) |
LOCALAI_CLAUDE_BINARY |
claude CLI 路径 |
MIT