npm package: @nogataka/claude-code-proxy-ts
Description: > **Quick Start** > ```bash > npx @nogataka/claude-code-proxy-ts@latest --config ~/.claude-code-proxy-ts/config.json > ``` > 初回は設定ファイルが自動生成されます。`--config` を省略しても `~/.claude-code-proxy-ts/config.json` にテンプレートが作成されるため、API キーとモデルを追記してご利用ください。
Latest version: 0.0.4

# Claude Code Proxy (TypeScript)

> **Quick Start**
> ```bash
> npx @nogataka/claude-code-proxy-ts@latest --config ~/.claude-code-proxy-ts/config.json
> ```
> 初回は設定ファイルが自動生成されます。`--config` を省略しても `~/.claude-code-proxy-ts/config.json` にテンプレートが作成されるため、API キーとモデルを追記してご利用ください。

Claude Code Proxy (TypeScript版) は、Anthropic Claude Code API 互換のリクエストを OpenAI / Azure OpenAI / Anthropic など複数プロバイダーへルーティングする Fastify + TypeScript 製プロキシです。Claude 形式の SSE ストリーミング、ツール呼び出し、マルチモーダル入力をサポートし、単一の設定ファイルで各プロバイダーの資格情報を管理できます。

---

## Table of Contents
- [Claude Code Proxy (TypeScript)](#claude-code-proxy-typescript)
  - [Table of Contents](#table-of-contents)
  - [Overview](#overview)
  - [Usage Guide](#usage-guide)
  - [Directory Layout](#directory-layout)
  - [Key Features](#key-features)
  - [Architecture](#architecture)
  - [Getting Started](#getting-started)
    - [npx でのワンライナー起動](#npx-でのワンライナー起動)
  - [Configuration](#configuration)
    - [Adapter の挙動](#adapter-の挙動)
  - [Development Workflow](#development-workflow)
  - [Testing](#testing)
  - [Roadmap](#roadmap)

---

## Overview
- `/v1/messages` を Claude 形式で受け取り、プロバイダー毎の Chat Completions API へ転送
- OpenAI / Azure OpenAI / Anthropic など複数プロバイダーを JSON 設定で切り替え
- Claude スタイルの SSE (`message_start`, `content_block_delta` など) をストリーミングで返却
- 任意のクライアント API キー検証、詳細なエラーメッセージ、ヘルスチェック・接続テストを提供

---

## Usage Guide

1. **要件の準備**  
   Node.js 20 以上と pnpm 8 以上を用意します。未インストールの場合は以下を実行してください。
   ```bash
   corepack enable         # Node.js 20 では pnpm が同梱されています
   corepack prepare pnpm@10.8.1 --activate
   ```

2. **リポジトリの取得**  
   ```bash
   git clone https://github.com/nogataka/claude-code-proxy-ts.git
   cd claude-code-proxy-ts
   pnpm install
   ```

3. **設定ファイルの生成**  
   初回はテンプレートを生成してから内容を編集します。任意のパスを指定して生成すると差分確認がしやすくなります。
   ```bash
   pnpm start -- --config ./config.local.json   # 生成後にサーバーはそのまま終了させて構いません
   ```

4. **設定の編集**  
   生成された JSON を開き、各プロバイダーの `apiKey`、`baseUrl`、モデルマッピング (`models.big/middle/small`) を実運用値に書き換えます。
   - Azure を使う場合は `baseUrl` に `/deployments/` を含めず、`models.big` などにデプロイメント名を指定します。
   - クライアントからのアクセス制限を行う場合は `client.expectedApiKey` に共有キーを設定し、`x-api-key` ヘッダー経由で提示させてください。

5. **サーバーの起動**  
   開発中はホットリロード付きで起動し、本番相当で動かすときは `start` スクリプトを使用します。
   ```bash
   pnpm dev      # 開発用途
   # もしくは
   pnpm start    # 本番相当（tsx を介さず実行）
   ```

6. **動作確認**  
   起動後にヘルスチェックと接続テストで疎通を確認します。
   ```bash
   curl http://localhost:8082/health
   curl http://localhost:8082/test-connection
   ```

7. **クライアントから利用**  
   Claude CLI や任意の HTTP クライアントから以下のようにベース URL を指定します。Claude CLI 側で `v1/messages` が付与されるため、ここではホスト名のみを設定してください。
   ```bash
   # 既定プロバイダー (openai)
   ANTHROPIC_BASE_URL=http://localhost:8082 claude

   # Azure / Ollama / Databricks へ切り替えたい場合
   ANTHROPIC_BASE_URL=http://localhost:8082/azure claude
   ANTHROPIC_BASE_URL=http://localhost:8082/ollama claude
   ANTHROPIC_BASE_URL=http://localhost:8082/databricks claude
   ```

   OpenAI / Codex 互換クライアントからは `/v1/chat/completions` エンドポイントをそのまま利用できます。ルート `openai`・`azure`・`ollama` で同一の OpenAI SDK を介して処理されるため、特別な変換は不要です。


8. **API リクエストの検証**  
   ログレベルを `config.json` の `logLevel` で調整し、`debug` にすると変換されたリクエスト/レスポンスが `stdout` に出力されます。問題があれば `pnpm lint` や `CI=1 pnpm test -- --run` で品質ゲートを通過していることを確認してください。

---

## Directory Layout
```
claude-code-proxy-ts/
├── README.md
├── package.json / pnpm-lock.yaml
├── tsconfig.json / vitest.config.ts
├── config.json (sample)
├── src/
│   ├── main.ts                 # Fastify エントリポイント
│   ├── api/endpoints.ts        # HTTP ルーティング
│   ├── conversion/
│   │   ├── request_converter.ts    # Claude → Provider 変換
│   │   └── response_converter.ts   # Provider → Claude (同期 & ストリーミング)
│   ├── core/
│   │   ├── config.ts           # JSON 設定ローダー
│   │   ├── client.ts           # Provider クライアント (OpenAI / Azure)
│   │   ├── logging.ts          # ログレベル管理
│   │   └── model_manager.ts    # Claude モデル → Provider モデル変換
│   ├── models/                 # Zod スキーマ & 型定義
│   └── core/constants.ts       # ロール / イベント定数
├── tests/
│   ├── setup.ts                # テスト用設定ファイル生成
│   ├── conversion.test.ts      # リクエスト変換テスト
│   ├── response_converter.test.ts  # SSE 変換テスト
│   └── client.test.ts          # エラー分類テスト
```

---

## Key Features
- **エンドポイント**: `/v1/messages`, `/:providerId/v1/messages`, `/v1/messages/count_tokens`, `/health`, `/test-connection`
- **マルチプロバイダー対応**: JSON 設定で API キー / ベース URL / モデルを切り替え、`/:providerId` プレフィックスで明示的に選択
- **Claude ↔ Provider 変換**: システムプロンプト・ツール呼び出し・マルチモーダル入力・停止シーケンスを忠実に変換
- **SSE ストリーミング**: 中断検知付きで Claude イベントを逐次送出、ツール引数 JSON のインクリメンタル転送に対応
- **公式 Ollama サポート**: `ollama` SDK を用いてチャット/ストリーミング/structured output を処理し、OpenAI 互換のツール呼び出しもマッピング
- **OpenAI Chat Completions API**: `/v1/chat/completions` を追加し、OpenAI/Azure/Ollama を OpenAI SDK 経由でそのまま中継
- **Azure サポート**: `apiVersion`・`deployment` を指定すると Azure OpenAI クライアントに自動切替
- **セキュリティ / 観測性**: クライアント API キー認証、詳細なエラーログ、疎通テスト API を同梱

---

## Architecture
```
Fastify (src/main.ts)
  → registerApiRoutes (src/api/endpoints.ts)
      → Claude リクエスト検証 (Zod)
      → convertClaudeToOpenAI (request_converter.ts)
      → Provider Client (core/client.ts)
          → OpenAI | AzureOpenAI
      → convertOpenAIToClaudeResponse / convertOpenAIStreamingToClaudeWithCancellation
      → fastify-sse-v2 で SSE 配信
```
- AbortController でストリーミング中のキャンセルを管理
- Usage トークン情報やエラー内容を Claude 形式へ再構築
- `getConfig()` は初回アクセス時に `~/.claude-code-proxy-ts/config.json` を生成・キャッシュ

---

## Getting Started
1. **依存関係のインストール**
   ```bash
   pnpm install
   ```
2. **設定ファイルを用意**
   ```bash
   pnpm start -- --config ./config.json   # 任意パスを渡すと指定先を生成
   ```
   初回起動時に設定ファイルが存在しない場合、`~/.claude-code-proxy-ts/config.json` (もしくは `--config` で指定したパス) がテンプレート付きで生成されます。API キーやモデル名を編集してください。
3. **開発モードで起動**
   ```bash
   pnpm dev      # tsx watch src/main.ts
   ```
4. **プロダクション相当で起動**
   ```bash
   pnpm start    # node --import tsx src/main.ts
   ```
5. **Claude CLI からプロキシを指定**
   ```bash
   ANTHROPIC_BASE_URL=http://localhost:8082 claude
   # プロバイダー個別指定: http://localhost:8082/azure など
   ```

### npx でのワンライナー起動
```bash
npx @nogataka/claude-code-proxy-ts@latest --config ~/.claude-code-proxy-ts/config.json
```
`--config` を省略するとデフォルトの `~/.claude-code-proxy-ts/config.json` を利用します。

---

## Configuration
設定は JSON ファイル 1 つで管理します。サンプル構造:

```json
{
  "logLevel": "warning",
  "server": { "host": "0.0.0.0", "port": 8082 },
  "limits": { "maxTokens": 4096, "minTokens": 256, "requestTimeoutSec": 90, "maxRetries": 2 },
  "client": { "expectedApiKey": "" },
  "providers": {
    "openai": {
      "adapter": "openai",
      "apiKey": "sk-...",
      "baseUrl": "https://api.openai.com/v1",
      "models": { "big": "gpt-4o", "middle": "gpt-4o", "small": "gpt-4o-mini" }
    },
    "anthropic": {
      "adapter": "openai",
      "apiKey": "anthropic-...",
      "baseUrl": "https://api.anthropic.com/v1",
      "models": { "big": "claude-3-opus", "middle": "claude-3-sonnet", "small": "claude-3-haiku" }
    },
    "azure": {
      "adapter": "azure",
      "apiKey": "azure-...",
      "baseUrl": "https://<resource>.openai.azure.com/",
      "models": { "big": "gpt-4o", "middle": "gpt-4o", "small": "gpt-4o-mini" },
      "azure": { "apiVersion": "2024-05-01-preview", "deployment": "gpt4o" }
    },
    "ollama": {
      "adapter": "ollama",
      "baseUrl": "http://localhost:11434",
      "models": { "big": "llama3.1", "middle": "llama3", "small": "llama3.1:8b" },
      "options": { "path": "/api/chat", "stream": true }
    },
    "databricks": {
      "adapter": "databricks",
      "baseUrl": "https://adb-<workspace>.azuredatabricks.net",
      "models": { "big": "databricks-claude-sonnet-4" },
      "options": {
        "path": "/serving-endpoints/databricks-claude-sonnet-4/invocations",
        "headers": {
          "Content-Type": "application/json",
          "Authorization": "Bearer YOUR_DATABRICKS_TOKEN"
        },
        "stream": false
      }
    }
  },
  "routing": { "defaultProvider": "openai", "fallbackOrder": ["azure", "ollama", "databricks"] }
}
```

- `providers` キーは任意の ID を付与可能 (`openai`, `azure`, `ollama`, `databricks` など)。`/:providerId` プレフィックスで選択します。
- `adapter` で呼び出し方式を指定します。`openai`(デフォルト) / `azure` / `ollama` / `databricks` をサポート。
- `options.path` でベース URL に連結する相対パス、`options.headers` で追加ヘッダーを定義できます。`options.stream` を `true` にするとアダプター側でストリーミングを要求します（`ollama` 用）。
- Azure の `baseUrl` には `/deployments/` を含めず、`models.big/middle/small` に設定した値を Azure デプロイメント名として扱います (モデル未指定の場合は `big` を使用)。
- `client.expectedApiKey` を設定すると、クライアントは `x-api-key` か Bearer トークンで同キーを提示する必要があります。
- `limits.maxTokens` / `minTokens` / `requestTimeoutSec` / `maxRetries` は共通デフォルトを制御。Azure の `apiVersion` が 2024-05-01 以降なら `max_completion_tokens` を利用します。

#### Model Mapping
- `/v1/messages`（Claude 互換ルート）では、リクエストに含まれる Claude モデル名を `model_manager` が `providers.<id>.models.{small|middle|big}` の優先順位に従って変換してからプロバイダーへ送信します。例：`haiku → small → middle → big`、`sonnet → middle → big → small`、`opus → big → middle → small`。該当がなければ `big → middle → small` の順に探索します。
- プロバイダーがどのモデルで応答しても、Claude クライアントへ返すレスポンスには元の Claude モデル名が保持されます。
- `/v1/chat/completions`（OpenAI/Codex 互換ルート）ではマッピングを行わず、クライアントが指定した `model` をそのまま OpenAI SDK（OpenAI/Azure/Ollama 共通）に渡します。

### Adapter の挙動

- `openai`: OpenAI / Anthropic など Chat Completions 互換 API を想定。既存の変換・ストリーミング処理が利用されます。
- `azure`: OpenAI 互換に加えて `azure.apiVersion` / `deployment` を使った Azure OpenAI 呼び出し。
- `ollama`: 公式 `ollama` JS SDK 経由でローカル Ollama に接続。`baseUrl` を指定するだけでチャット/ストリーミング/ツール呼び出し/構造化出力（JSON スキーマ）まで動作します。
- `databricks`: Databricks Serving Endpoints など OpenAI 互換 REST API を呼び出します。`options.path` や `options.headers` でエンドポイント／トークンを指定し、`options.stream: false` にすると完全同期モードになります。

---

## Development Workflow
- **起動**: `pnpm dev` (ホットリロード) / `pnpm start` (本番モード)
- **Lint**: `pnpm lint`
- **Format**: `pnpm format`
- **ビルド**: `pnpm build`
- **ログレベル**: `config.json` の `logLevel` を `debug` / `info` / `warning` / `error` / `critical` から選択
- **Config リフレッシュ**: テストや再読み込みが必要な場合は `resetConfigForTesting()` / `resetOpenAIClient()` を利用 (`tests/setup.ts` で自動実行)

---

## Testing
```bash
CI=1 pnpm test -- --run
```
Vitest が JSON 設定を一時ディレクトリに生成してから各テストを実行します。ストリーミング変換・エラー分類・リクエスト変換の回帰テストが含まれます。

---

## Roadmap
1. **End-to-End HTTP Tests**: Fastify サーバーを立ち上げた実運用経路の自動テスト
2. **拡張プロバイダーサポート**: Ollama や他社互換 API へのドライバ追加
3. **デプロイメント支援**: Dockerfile / Helm Chart の提供
4. **Metrics & Tracing**: OpenTelemetry など観測基盤への出力
5. **Config UI**: 設定 JSON の編集を支援する簡易 CLI / UI

バグ報告・機能要望・プルリクエストは歓迎しています。