cli2api 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cli2api-0.1.0/.dockerignore +74 -0
- cli2api-0.1.0/.env.example +22 -0
- cli2api-0.1.0/.github/workflows/publish.yml +27 -0
- cli2api-0.1.0/.gitignore +56 -0
- cli2api-0.1.0/Dockerfile +44 -0
- cli2api-0.1.0/PKG-INFO +217 -0
- cli2api-0.1.0/README.md +202 -0
- cli2api-0.1.0/cli2api/__init__.py +3 -0
- cli2api-0.1.0/cli2api/__main__.py +22 -0
- cli2api-0.1.0/cli2api/api/__init__.py +5 -0
- cli2api-0.1.0/cli2api/api/dependencies.py +38 -0
- cli2api-0.1.0/cli2api/api/router.py +12 -0
- cli2api-0.1.0/cli2api/api/utils.py +15 -0
- cli2api-0.1.0/cli2api/api/v1/__init__.py +5 -0
- cli2api-0.1.0/cli2api/api/v1/chat.py +378 -0
- cli2api-0.1.0/cli2api/api/v1/models.py +52 -0
- cli2api-0.1.0/cli2api/api/v1/responses.py +255 -0
- cli2api-0.1.0/cli2api/config/__init__.py +5 -0
- cli2api-0.1.0/cli2api/config/settings.py +86 -0
- cli2api-0.1.0/cli2api/main.py +143 -0
- cli2api-0.1.0/cli2api/providers/__init__.py +5 -0
- cli2api-0.1.0/cli2api/providers/claude.py +440 -0
- cli2api-0.1.0/cli2api/schemas/__init__.py +36 -0
- cli2api-0.1.0/cli2api/schemas/internal.py +25 -0
- cli2api-0.1.0/cli2api/schemas/openai.py +229 -0
- cli2api-0.1.0/cli2api/streaming/__init__.py +5 -0
- cli2api-0.1.0/cli2api/streaming/sse.py +41 -0
- cli2api-0.1.0/cli2api/tools/__init__.py +5 -0
- cli2api-0.1.0/cli2api/tools/handler.py +396 -0
- cli2api-0.1.0/cli2api/utils/__init__.py +0 -0
- cli2api-0.1.0/cli2api/utils/logging.py +109 -0
- cli2api-0.1.0/cli2api.sh +9 -0
- cli2api-0.1.0/docker-compose.yaml +55 -0
- cli2api-0.1.0/pyproject.toml +33 -0
- cli2api-0.1.0/tests/__init__.py +1 -0
- cli2api-0.1.0/tests/conftest.py +167 -0
- cli2api-0.1.0/tests/test_api.py +468 -0
- cli2api-0.1.0/tests/test_config.py +156 -0
- cli2api-0.1.0/tests/test_integration.py +221 -0
- cli2api-0.1.0/tests/test_providers.py +197 -0
- cli2api-0.1.0/tests/test_schemas.py +301 -0
- cli2api-0.1.0/tests/test_streaming.py +132 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
build/
|
|
8
|
+
develop-eggs/
|
|
9
|
+
dist/
|
|
10
|
+
downloads/
|
|
11
|
+
eggs/
|
|
12
|
+
.eggs/
|
|
13
|
+
lib/
|
|
14
|
+
lib64/
|
|
15
|
+
parts/
|
|
16
|
+
sdist/
|
|
17
|
+
var/
|
|
18
|
+
wheels/
|
|
19
|
+
pip-wheel-metadata/
|
|
20
|
+
share/python-wheels/
|
|
21
|
+
*.egg-info/
|
|
22
|
+
.installed.cfg
|
|
23
|
+
*.egg
|
|
24
|
+
|
|
25
|
+
# Testing
|
|
26
|
+
.pytest_cache/
|
|
27
|
+
.coverage
|
|
28
|
+
.coverage.*
|
|
29
|
+
htmlcov/
|
|
30
|
+
.tox/
|
|
31
|
+
.nox/
|
|
32
|
+
.hypothesis/
|
|
33
|
+
tests/
|
|
34
|
+
|
|
35
|
+
# Environment
|
|
36
|
+
.env
|
|
37
|
+
.venv
|
|
38
|
+
env/
|
|
39
|
+
venv/
|
|
40
|
+
ENV/
|
|
41
|
+
env.bak/
|
|
42
|
+
venv.bak/
|
|
43
|
+
|
|
44
|
+
# IDEs
|
|
45
|
+
.vscode/
|
|
46
|
+
.idea/
|
|
47
|
+
*.swp
|
|
48
|
+
*.swo
|
|
49
|
+
*~
|
|
50
|
+
.DS_Store
|
|
51
|
+
|
|
52
|
+
# Git
|
|
53
|
+
.git/
|
|
54
|
+
.gitignore
|
|
55
|
+
.gitattributes
|
|
56
|
+
|
|
57
|
+
# Docker
|
|
58
|
+
Dockerfile
|
|
59
|
+
docker-compose.yaml
|
|
60
|
+
.dockerignore
|
|
61
|
+
|
|
62
|
+
# Documentation
|
|
63
|
+
*.md
|
|
64
|
+
README.md
|
|
65
|
+
|
|
66
|
+
# CI/CD
|
|
67
|
+
.github/
|
|
68
|
+
.gitlab-ci.yml
|
|
69
|
+
|
|
70
|
+
# Logs
|
|
71
|
+
*.log
|
|
72
|
+
|
|
73
|
+
# Claude
|
|
74
|
+
.claude/
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# CLI2API Configuration
|
|
2
|
+
# Copy this file to .env and customize as needed
|
|
3
|
+
|
|
4
|
+
# Server settings
|
|
5
|
+
CLI2API_HOST=0.0.0.0
|
|
6
|
+
CLI2API_PORT=8000
|
|
7
|
+
CLI2API_DEBUG=false
|
|
8
|
+
|
|
9
|
+
# CLI executable path (auto-detected if not set)
|
|
10
|
+
# CLI2API_CLAUDE_CLI_PATH=/opt/homebrew/bin/claude
|
|
11
|
+
|
|
12
|
+
# Timeout (in seconds)
|
|
13
|
+
CLI2API_DEFAULT_TIMEOUT=300
|
|
14
|
+
|
|
15
|
+
# Default model
|
|
16
|
+
CLI2API_DEFAULT_MODEL=sonnet
|
|
17
|
+
|
|
18
|
+
# Custom models (comma-separated)
|
|
19
|
+
# CLI2API_CLAUDE_MODELS=sonnet,opus,haiku
|
|
20
|
+
|
|
21
|
+
# Logging
|
|
22
|
+
CLI2API_LOG_LEVEL=INFO
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
publish:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- uses: actions/checkout@v4
|
|
12
|
+
|
|
13
|
+
- name: Set up Python
|
|
14
|
+
uses: actions/setup-python@v5
|
|
15
|
+
with:
|
|
16
|
+
python-version: "3.11"
|
|
17
|
+
|
|
18
|
+
- name: Install build tools
|
|
19
|
+
run: pip install build
|
|
20
|
+
|
|
21
|
+
- name: Build package
|
|
22
|
+
run: python -m build
|
|
23
|
+
|
|
24
|
+
- name: Publish to PyPI
|
|
25
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
26
|
+
with:
|
|
27
|
+
password: ${{ secrets.PYPI_API_TOKEN }}
|
cli2api-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
build/
|
|
8
|
+
develop-eggs/
|
|
9
|
+
dist/
|
|
10
|
+
downloads/
|
|
11
|
+
eggs/
|
|
12
|
+
.eggs/
|
|
13
|
+
lib/
|
|
14
|
+
lib64/
|
|
15
|
+
parts/
|
|
16
|
+
sdist/
|
|
17
|
+
var/
|
|
18
|
+
wheels/
|
|
19
|
+
pip-wheel-metadata/
|
|
20
|
+
share/python-wheels/
|
|
21
|
+
*.egg-info/
|
|
22
|
+
.installed.cfg
|
|
23
|
+
*.egg
|
|
24
|
+
PIPFILE.lock
|
|
25
|
+
|
|
26
|
+
# Testing
|
|
27
|
+
.pytest_cache/
|
|
28
|
+
.coverage
|
|
29
|
+
.coverage.*
|
|
30
|
+
htmlcov/
|
|
31
|
+
.tox/
|
|
32
|
+
.nox/
|
|
33
|
+
.hypothesis/
|
|
34
|
+
|
|
35
|
+
# Environment
|
|
36
|
+
.env
|
|
37
|
+
.venv
|
|
38
|
+
env/
|
|
39
|
+
venv/
|
|
40
|
+
ENV/
|
|
41
|
+
env.bak/
|
|
42
|
+
venv.bak/
|
|
43
|
+
|
|
44
|
+
# IDEs
|
|
45
|
+
.vscode/
|
|
46
|
+
.idea/
|
|
47
|
+
*.swp
|
|
48
|
+
*.swo
|
|
49
|
+
*~
|
|
50
|
+
.DS_Store
|
|
51
|
+
|
|
52
|
+
# Logs
|
|
53
|
+
*.log
|
|
54
|
+
|
|
55
|
+
# Claude
|
|
56
|
+
.claude/
|
cli2api-0.1.0/Dockerfile
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Multi-stage build for CLI2API
|
|
2
|
+
FROM python:3.11-slim as base
|
|
3
|
+
|
|
4
|
+
# Set environment variables
|
|
5
|
+
ENV PYTHONUNBUFFERED=1 \
|
|
6
|
+
PYTHONDONTWRITEBYTECODE=1 \
|
|
7
|
+
PIP_NO_CACHE_DIR=1 \
|
|
8
|
+
PIP_DISABLE_PIP_VERSION_CHECK=1
|
|
9
|
+
|
|
10
|
+
# Create app user
|
|
11
|
+
RUN useradd -m -u 1000 cli2api && \
|
|
12
|
+
mkdir -p /app && \
|
|
13
|
+
chown -R cli2api:cli2api /app
|
|
14
|
+
|
|
15
|
+
WORKDIR /app
|
|
16
|
+
|
|
17
|
+
# Install system dependencies
|
|
18
|
+
RUN apt-get update && \
|
|
19
|
+
apt-get install -y --no-install-recommends \
|
|
20
|
+
curl \
|
|
21
|
+
ca-certificates && \
|
|
22
|
+
rm -rf /var/lib/apt/lists/*
|
|
23
|
+
|
|
24
|
+
# Copy dependency files
|
|
25
|
+
COPY --chown=cli2api:cli2api pyproject.toml ./
|
|
26
|
+
|
|
27
|
+
# Install Python dependencies
|
|
28
|
+
RUN pip install -e .
|
|
29
|
+
|
|
30
|
+
# Copy application code
|
|
31
|
+
COPY --chown=cli2api:cli2api cli2api/ ./cli2api/
|
|
32
|
+
|
|
33
|
+
# Switch to non-root user
|
|
34
|
+
USER cli2api
|
|
35
|
+
|
|
36
|
+
# Expose port
|
|
37
|
+
EXPOSE 8000
|
|
38
|
+
|
|
39
|
+
# Health check
|
|
40
|
+
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
|
41
|
+
CMD curl -f http://localhost:8000/health || exit 1
|
|
42
|
+
|
|
43
|
+
# Run the application
|
|
44
|
+
CMD ["uvicorn", "cli2api.main:app", "--host", "0.0.0.0", "--port", "8000"]
|
cli2api-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: cli2api
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: OpenAI-compatible API over Claude Code CLI
|
|
5
|
+
Requires-Python: >=3.11
|
|
6
|
+
Requires-Dist: fastapi>=0.115.0
|
|
7
|
+
Requires-Dist: pydantic-settings>=2.6.0
|
|
8
|
+
Requires-Dist: pydantic>=2.10.0
|
|
9
|
+
Requires-Dist: uvicorn[standard]>=0.32.0
|
|
10
|
+
Provides-Extra: dev
|
|
11
|
+
Requires-Dist: httpx>=0.28.0; extra == 'dev'
|
|
12
|
+
Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
|
|
13
|
+
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
|
|
16
|
+
# CLI2API
|
|
17
|
+
|
|
18
|
+
OpenAI-compatible API over Claude Code CLI.
|
|
19
|
+
|
|
20
|
+
## Why CLI2API?
|
|
21
|
+
|
|
22
|
+
Claude Code CLI is powerful but not all tools support it directly. CLI2API bridges this gap by exposing Claude Code as an OpenAI-compatible API.
|
|
23
|
+
|
|
24
|
+
**Use Cases:**
|
|
25
|
+
|
|
26
|
+
- **IDE Integration** — Connect Kilo Code, Roo Code, Cursor, or other editors that support OpenAI API
|
|
27
|
+
- **Custom Applications** — Build apps using familiar OpenAI SDK instead of spawning CLI processes
|
|
28
|
+
- **Team Sharing** — Run one CLI2API server and share Claude access across your team
|
|
29
|
+
- **Tool Compatibility** — Use Claude with any tool that supports OpenAI API format (LangChain, AutoGPT, etc.)
|
|
30
|
+
|
|
31
|
+
## Requirements
|
|
32
|
+
|
|
33
|
+
- Python 3.11+
|
|
34
|
+
- [Claude Code CLI](https://docs.anthropic.com/en/docs/claude-code) installed and authenticated
|
|
35
|
+
|
|
36
|
+
## Installation
|
|
37
|
+
|
|
38
|
+
### Quick Start
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# Clone the repository
|
|
42
|
+
git clone https://github.com/anoxis/CLI2API.git
|
|
43
|
+
cd CLI2API
|
|
44
|
+
|
|
45
|
+
# Install dependencies
|
|
46
|
+
pip install -e .
|
|
47
|
+
|
|
48
|
+
# Start server
|
|
49
|
+
./cli2api.sh
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Add to PATH (Recommended)
|
|
53
|
+
|
|
54
|
+
For easy access from anywhere:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
# Add to your shell profile (~/.bashrc, ~/.zshrc, etc.)
|
|
58
|
+
export PATH="$PATH:/path/to/CLI2API"
|
|
59
|
+
|
|
60
|
+
# Then run from anywhere
|
|
61
|
+
cli2api.sh
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Running After Installation
|
|
65
|
+
|
|
66
|
+
Once installed, you can start the server in several ways:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
# Using the script (recommended)
|
|
70
|
+
./cli2api.sh
|
|
71
|
+
|
|
72
|
+
# Using Python module
|
|
73
|
+
python -m cli2api
|
|
74
|
+
|
|
75
|
+
# Using uvicorn directly
|
|
76
|
+
uvicorn cli2api.main:app --host 0.0.0.0 --port 8000
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Docker
|
|
80
|
+
|
|
81
|
+
Docker requires the repository to be cloned first:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
# Clone and build
|
|
85
|
+
git clone https://github.com/anoxis/CLI2API.git
|
|
86
|
+
cd CLI2API
|
|
87
|
+
docker build -t cli2api .
|
|
88
|
+
|
|
89
|
+
# Run with Claude CLI mounted from host
|
|
90
|
+
docker run -p 8000:8000 \
|
|
91
|
+
-v $(which claude):/usr/local/bin/claude:ro \
|
|
92
|
+
-e CLI2API_CLAUDE_CLI_PATH=/usr/local/bin/claude \
|
|
93
|
+
cli2api
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Or use docker-compose:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
# Edit docker-compose.yaml to mount your Claude CLI path
|
|
100
|
+
docker-compose up -d
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Development
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
pip install -e ".[dev]"
|
|
107
|
+
pytest tests/ -v
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## IDE Integration
|
|
111
|
+
|
|
112
|
+
### Kilo Code / Roo Code
|
|
113
|
+
|
|
114
|
+
1. Start CLI2API server: `./cli2api.sh`
|
|
115
|
+
2. Open extension settings
|
|
116
|
+
3. Add custom provider:
|
|
117
|
+
- **Provider Name:** `CLI2API` (or any name)
|
|
118
|
+
- **API Base URL:** `http://localhost:8000/v1`
|
|
119
|
+
- **API Key:** `not-needed` (any non-empty value)
|
|
120
|
+
- **Model:** `sonnet` (or `opus`, `haiku`)
|
|
121
|
+
|
|
122
|
+
### Cursor / Continue
|
|
123
|
+
|
|
124
|
+
1. Start CLI2API server
|
|
125
|
+
2. Settings → Models → Add Model
|
|
126
|
+
3. Configure:
|
|
127
|
+
- **API Base:** `http://localhost:8000/v1`
|
|
128
|
+
- **API Key:** `any-value`
|
|
129
|
+
- **Model:** `sonnet`
|
|
130
|
+
|
|
131
|
+
### Generic OpenAI-compatible client
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
from openai import OpenAI
|
|
135
|
+
|
|
136
|
+
client = OpenAI(
|
|
137
|
+
base_url="http://localhost:8000/v1",
|
|
138
|
+
api_key="not-needed"
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
response = client.chat.completions.create(
|
|
142
|
+
model="sonnet",
|
|
143
|
+
messages=[{"role": "user", "content": "Hello!"}]
|
|
144
|
+
)
|
|
145
|
+
print(response.choices[0].message.content)
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Usage
|
|
149
|
+
|
|
150
|
+
### Test with curl
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
# Health check
|
|
154
|
+
curl http://localhost:8000/health
|
|
155
|
+
|
|
156
|
+
# List models
|
|
157
|
+
curl http://localhost:8000/v1/models
|
|
158
|
+
|
|
159
|
+
# Chat completion
|
|
160
|
+
curl http://localhost:8000/v1/chat/completions \
|
|
161
|
+
-H "Content-Type: application/json" \
|
|
162
|
+
-d '{"model": "sonnet", "messages": [{"role": "user", "content": "Hello"}]}'
|
|
163
|
+
|
|
164
|
+
# Streaming
|
|
165
|
+
curl http://localhost:8000/v1/chat/completions \
|
|
166
|
+
-H "Content-Type: application/json" \
|
|
167
|
+
-d '{"model": "sonnet", "messages": [{"role": "user", "content": "Hello"}], "stream": true}'
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Configuration
|
|
171
|
+
|
|
172
|
+
Environment variables (prefix `CLI2API_`):
|
|
173
|
+
|
|
174
|
+
| Variable | Default | Description |
|
|
175
|
+
|----------|---------|-------------|
|
|
176
|
+
| `HOST` | `0.0.0.0` | Server host |
|
|
177
|
+
| `PORT` | `8000` | Server port |
|
|
178
|
+
| `CLAUDE_CLI_PATH` | auto-detect | Path to Claude CLI executable |
|
|
179
|
+
| `DEFAULT_TIMEOUT` | `300` | CLI execution timeout (seconds) |
|
|
180
|
+
| `DEFAULT_MODEL` | `sonnet` | Default model |
|
|
181
|
+
| `CLAUDE_MODELS` | `sonnet,opus,haiku` | Available models (comma-separated) |
|
|
182
|
+
| `LOG_LEVEL` | `INFO` | Logging level |
|
|
183
|
+
| `LOG_JSON` | `false` | JSON format logging |
|
|
184
|
+
| `DEBUG` | `false` | Debug mode |
|
|
185
|
+
|
|
186
|
+
Copy `.env.example` to `.env` for local configuration.
|
|
187
|
+
|
|
188
|
+
## Available Models
|
|
189
|
+
|
|
190
|
+
| Model ID | Description |
|
|
191
|
+
|----------|-------------|
|
|
192
|
+
| `sonnet` | Claude Sonnet (default) |
|
|
193
|
+
| `opus` | Claude Opus |
|
|
194
|
+
| `haiku` | Claude Haiku |
|
|
195
|
+
|
|
196
|
+
## API Endpoints
|
|
197
|
+
|
|
198
|
+
| Endpoint | Description |
|
|
199
|
+
|----------|-------------|
|
|
200
|
+
| `GET /health` | Health check |
|
|
201
|
+
| `GET /` | API info |
|
|
202
|
+
| `GET /v1/models` | List available models |
|
|
203
|
+
| `GET /v1/models/{id}` | Get model info |
|
|
204
|
+
| `POST /v1/chat/completions` | Chat completions (OpenAI compatible) |
|
|
205
|
+
| `POST /v1/responses` | Responses API (OpenAI compatible) |
|
|
206
|
+
|
|
207
|
+
## Security Notice
|
|
208
|
+
|
|
209
|
+
CLI2API does **not** implement authentication. It is designed for **local use only**.
|
|
210
|
+
|
|
211
|
+
- Do not expose to the internet without additional security measures
|
|
212
|
+
- Use behind a reverse proxy with authentication if network access is needed
|
|
213
|
+
- The API inherits permissions from the Claude CLI authentication on the host
|
|
214
|
+
|
|
215
|
+
## License
|
|
216
|
+
|
|
217
|
+
MIT
|
cli2api-0.1.0/README.md
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
# CLI2API
|
|
2
|
+
|
|
3
|
+
OpenAI-compatible API over Claude Code CLI.
|
|
4
|
+
|
|
5
|
+
## Why CLI2API?
|
|
6
|
+
|
|
7
|
+
Claude Code CLI is powerful but not all tools support it directly. CLI2API bridges this gap by exposing Claude Code as an OpenAI-compatible API.
|
|
8
|
+
|
|
9
|
+
**Use Cases:**
|
|
10
|
+
|
|
11
|
+
- **IDE Integration** — Connect Kilo Code, Roo Code, Cursor, or other editors that support OpenAI API
|
|
12
|
+
- **Custom Applications** — Build apps using familiar OpenAI SDK instead of spawning CLI processes
|
|
13
|
+
- **Team Sharing** — Run one CLI2API server and share Claude access across your team
|
|
14
|
+
- **Tool Compatibility** — Use Claude with any tool that supports OpenAI API format (LangChain, AutoGPT, etc.)
|
|
15
|
+
|
|
16
|
+
## Requirements
|
|
17
|
+
|
|
18
|
+
- Python 3.11+
|
|
19
|
+
- [Claude Code CLI](https://docs.anthropic.com/en/docs/claude-code) installed and authenticated
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
### Quick Start
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
# Clone the repository
|
|
27
|
+
git clone https://github.com/anoxis/CLI2API.git
|
|
28
|
+
cd CLI2API
|
|
29
|
+
|
|
30
|
+
# Install dependencies
|
|
31
|
+
pip install -e .
|
|
32
|
+
|
|
33
|
+
# Start server
|
|
34
|
+
./cli2api.sh
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Add to PATH (Recommended)
|
|
38
|
+
|
|
39
|
+
For easy access from anywhere:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# Add to your shell profile (~/.bashrc, ~/.zshrc, etc.)
|
|
43
|
+
export PATH="$PATH:/path/to/CLI2API"
|
|
44
|
+
|
|
45
|
+
# Then run from anywhere
|
|
46
|
+
cli2api.sh
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Running After Installation
|
|
50
|
+
|
|
51
|
+
Once installed, you can start the server in several ways:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
# Using the script (recommended)
|
|
55
|
+
./cli2api.sh
|
|
56
|
+
|
|
57
|
+
# Using Python module
|
|
58
|
+
python -m cli2api
|
|
59
|
+
|
|
60
|
+
# Using uvicorn directly
|
|
61
|
+
uvicorn cli2api.main:app --host 0.0.0.0 --port 8000
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Docker
|
|
65
|
+
|
|
66
|
+
Docker requires the repository to be cloned first:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
# Clone and build
|
|
70
|
+
git clone https://github.com/anoxis/CLI2API.git
|
|
71
|
+
cd CLI2API
|
|
72
|
+
docker build -t cli2api .
|
|
73
|
+
|
|
74
|
+
# Run with Claude CLI mounted from host
|
|
75
|
+
docker run -p 8000:8000 \
|
|
76
|
+
-v $(which claude):/usr/local/bin/claude:ro \
|
|
77
|
+
-e CLI2API_CLAUDE_CLI_PATH=/usr/local/bin/claude \
|
|
78
|
+
cli2api
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Or use docker-compose:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
# Edit docker-compose.yaml to mount your Claude CLI path
|
|
85
|
+
docker-compose up -d
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Development
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
pip install -e ".[dev]"
|
|
92
|
+
pytest tests/ -v
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## IDE Integration
|
|
96
|
+
|
|
97
|
+
### Kilo Code / Roo Code
|
|
98
|
+
|
|
99
|
+
1. Start CLI2API server: `./cli2api.sh`
|
|
100
|
+
2. Open extension settings
|
|
101
|
+
3. Add custom provider:
|
|
102
|
+
- **Provider Name:** `CLI2API` (or any name)
|
|
103
|
+
- **API Base URL:** `http://localhost:8000/v1`
|
|
104
|
+
- **API Key:** `not-needed` (any non-empty value)
|
|
105
|
+
- **Model:** `sonnet` (or `opus`, `haiku`)
|
|
106
|
+
|
|
107
|
+
### Cursor / Continue
|
|
108
|
+
|
|
109
|
+
1. Start CLI2API server
|
|
110
|
+
2. Settings → Models → Add Model
|
|
111
|
+
3. Configure:
|
|
112
|
+
- **API Base:** `http://localhost:8000/v1`
|
|
113
|
+
- **API Key:** `any-value`
|
|
114
|
+
- **Model:** `sonnet`
|
|
115
|
+
|
|
116
|
+
### Generic OpenAI-compatible client
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
from openai import OpenAI
|
|
120
|
+
|
|
121
|
+
client = OpenAI(
|
|
122
|
+
base_url="http://localhost:8000/v1",
|
|
123
|
+
api_key="not-needed"
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
response = client.chat.completions.create(
|
|
127
|
+
model="sonnet",
|
|
128
|
+
messages=[{"role": "user", "content": "Hello!"}]
|
|
129
|
+
)
|
|
130
|
+
print(response.choices[0].message.content)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Usage
|
|
134
|
+
|
|
135
|
+
### Test with curl
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
# Health check
|
|
139
|
+
curl http://localhost:8000/health
|
|
140
|
+
|
|
141
|
+
# List models
|
|
142
|
+
curl http://localhost:8000/v1/models
|
|
143
|
+
|
|
144
|
+
# Chat completion
|
|
145
|
+
curl http://localhost:8000/v1/chat/completions \
|
|
146
|
+
-H "Content-Type: application/json" \
|
|
147
|
+
-d '{"model": "sonnet", "messages": [{"role": "user", "content": "Hello"}]}'
|
|
148
|
+
|
|
149
|
+
# Streaming
|
|
150
|
+
curl http://localhost:8000/v1/chat/completions \
|
|
151
|
+
-H "Content-Type: application/json" \
|
|
152
|
+
-d '{"model": "sonnet", "messages": [{"role": "user", "content": "Hello"}], "stream": true}'
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Configuration
|
|
156
|
+
|
|
157
|
+
Environment variables (prefix `CLI2API_`):
|
|
158
|
+
|
|
159
|
+
| Variable | Default | Description |
|
|
160
|
+
|----------|---------|-------------|
|
|
161
|
+
| `HOST` | `0.0.0.0` | Server host |
|
|
162
|
+
| `PORT` | `8000` | Server port |
|
|
163
|
+
| `CLAUDE_CLI_PATH` | auto-detect | Path to Claude CLI executable |
|
|
164
|
+
| `DEFAULT_TIMEOUT` | `300` | CLI execution timeout (seconds) |
|
|
165
|
+
| `DEFAULT_MODEL` | `sonnet` | Default model |
|
|
166
|
+
| `CLAUDE_MODELS` | `sonnet,opus,haiku` | Available models (comma-separated) |
|
|
167
|
+
| `LOG_LEVEL` | `INFO` | Logging level |
|
|
168
|
+
| `LOG_JSON` | `false` | JSON format logging |
|
|
169
|
+
| `DEBUG` | `false` | Debug mode |
|
|
170
|
+
|
|
171
|
+
Copy `.env.example` to `.env` for local configuration.
|
|
172
|
+
|
|
173
|
+
## Available Models
|
|
174
|
+
|
|
175
|
+
| Model ID | Description |
|
|
176
|
+
|----------|-------------|
|
|
177
|
+
| `sonnet` | Claude Sonnet (default) |
|
|
178
|
+
| `opus` | Claude Opus |
|
|
179
|
+
| `haiku` | Claude Haiku |
|
|
180
|
+
|
|
181
|
+
## API Endpoints
|
|
182
|
+
|
|
183
|
+
| Endpoint | Description |
|
|
184
|
+
|----------|-------------|
|
|
185
|
+
| `GET /health` | Health check |
|
|
186
|
+
| `GET /` | API info |
|
|
187
|
+
| `GET /v1/models` | List available models |
|
|
188
|
+
| `GET /v1/models/{id}` | Get model info |
|
|
189
|
+
| `POST /v1/chat/completions` | Chat completions (OpenAI compatible) |
|
|
190
|
+
| `POST /v1/responses` | Responses API (OpenAI compatible) |
|
|
191
|
+
|
|
192
|
+
## Security Notice
|
|
193
|
+
|
|
194
|
+
CLI2API does **not** implement authentication. It is designed for **local use only**.
|
|
195
|
+
|
|
196
|
+
- Do not expose to the internet without additional security measures
|
|
197
|
+
- Use behind a reverse proxy with authentication if network access is needed
|
|
198
|
+
- The API inherits permissions from the Claude CLI authentication on the host
|
|
199
|
+
|
|
200
|
+
## License
|
|
201
|
+
|
|
202
|
+
MIT
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""Entry point for running CLI2API as a module."""
|
|
2
|
+
|
|
3
|
+
import uvicorn
|
|
4
|
+
|
|
5
|
+
from cli2api.api.dependencies import get_settings
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def main():
|
|
9
|
+
"""Run the CLI2API server."""
|
|
10
|
+
settings = get_settings()
|
|
11
|
+
|
|
12
|
+
uvicorn.run(
|
|
13
|
+
"cli2api.main:app",
|
|
14
|
+
host=settings.host,
|
|
15
|
+
port=settings.port,
|
|
16
|
+
reload=settings.debug,
|
|
17
|
+
log_level=settings.log_level.lower(),
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
if __name__ == "__main__":
|
|
22
|
+
main()
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""FastAPI dependencies for dependency injection."""
|
|
2
|
+
|
|
3
|
+
from functools import lru_cache
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
from cli2api.config.settings import Settings
|
|
7
|
+
from cli2api.providers.claude import ClaudeCodeProvider
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@lru_cache
|
|
11
|
+
def get_settings() -> Settings:
|
|
12
|
+
"""Get cached application settings.
|
|
13
|
+
|
|
14
|
+
Returns:
|
|
15
|
+
Singleton Settings instance.
|
|
16
|
+
"""
|
|
17
|
+
return Settings()
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@lru_cache
|
|
21
|
+
def get_provider() -> ClaudeCodeProvider:
|
|
22
|
+
"""Get cached Claude provider.
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
Singleton ClaudeCodeProvider instance.
|
|
26
|
+
|
|
27
|
+
Raises:
|
|
28
|
+
RuntimeError: If Claude CLI is not configured.
|
|
29
|
+
"""
|
|
30
|
+
settings = get_settings()
|
|
31
|
+
if not settings.claude_cli_path:
|
|
32
|
+
raise RuntimeError("Claude CLI not found. Set CLI2API_CLAUDE_CLI_PATH.")
|
|
33
|
+
|
|
34
|
+
return ClaudeCodeProvider(
|
|
35
|
+
executable_path=Path(settings.claude_cli_path),
|
|
36
|
+
default_timeout=settings.default_timeout,
|
|
37
|
+
models=settings.get_claude_models(),
|
|
38
|
+
)
|