Metadata-Version: 2.4
Name: claude-code-server
Version: 0.1.0
Summary: Claude Code CLI wrapped as HTTP SSE server — reusable backend for any project
Project-URL: Homepage, https://github.com/KenyonY/claude-code-server
Project-URL: Repository, https://github.com/KenyonY/claude-code-server
License: MIT
Keywords: ai,chat,claude,claude-code,fastapi,sse
Classifier: Framework :: FastAPI
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Requires-Python: >=3.10
Requires-Dist: fastapi>=0.100.0
Requires-Dist: openpyxl>=3.1.0
Requires-Dist: pandas>=2.0.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: uvicorn[standard]>=0.20.0
Provides-Extra: dev
Requires-Dist: httpx; extra == 'dev'
Requires-Dist: pytest; extra == 'dev'
Requires-Dist: pytest-asyncio; extra == 'dev'
Description-Content-Type: text/markdown

# claude-code-server

Claude Code CLI wrapped as HTTP SSE server + reusable React chat UI.

## Quick Start

### Backend

```bash
pip install -e .
claude-code-server --working-dir /path/to/project --port 8333
```

### Embed in existing FastAPI app

```python
from claude_code_server import create_router, AgentConfig

router = create_router(AgentConfig(working_dir="/path/to/project"))
app.include_router(router, prefix="/agent")
```

### Dynamic config per request

```python
from claude_code_server import create_router, AgentConfig, ChatRequest

def config_factory(req: ChatRequest) -> AgentConfig:
    return AgentConfig(
        working_dir="/path/to/project",
        system_prompt="You are a helpful assistant for ...",
        env={"MY_VAR": "value"},
    )

router = create_router(config_factory=config_factory)
```

### Frontend

```tsx
import { Chat } from 'claude-code-chat'

<Chat
  apiBase="/api/agent"
  uploadUrl="/api/agent/upload"
  getHeaders={() => ({ Authorization: `Bearer ${token}` })}
  slashCommands={[
    { name: 'status', description: 'Check status', type: 'prompt', prompt: 'Show status' },
  ]}
/>
```

Or use individual components:

```tsx
import { useChat, ChatMessages, ChatInput } from 'claude-code-chat'

const { messages, send, cancel, isLoading, costInfo, uploadFile } = useChat({
  apiBase: '/api/agent',
  uploadUrl: '/api/agent/upload',
})

<ChatMessages messages={messages} isLoading={isLoading} costInfo={costInfo} />
<ChatInput onSend={send} isLoading={isLoading} onCancel={cancel} onUploadFile={uploadFile} />
```

## SSE Event Protocol

| Event | Data | Description |
|-------|------|-------------|
| `session` | `{session_id}` | Session created/resumed |
| `text` | `{content}` | Text delta |
| `thinking` | `{content}` | Thinking delta |
| `tool_call` | `{id, name, arguments}` | Tool invocation |
| `tool_result` | `{id, name, result, is_error}` | Tool result |
| `done` | `{cost, duration_ms}` | Turn complete |
| `error` | `{message}` | Error |

## API

### Backend

- `ClaudeAgent` — Core agent class
- `AgentConfig` — Configuration (working_dir, system_prompt, env, max_turns, ...)
- `ChatRequest` — Request model (prompt, session_id)
- `create_router(config?, config_factory?)` — FastAPI router factory
- `create_app(config?)` — Standalone FastAPI app

### Frontend

- `<Chat>` — Complete chat page (drop-in)
- `<ChatMessages>` — Message renderer
- `<ChatInput>` — Input with slash commands + file upload
- `useChat(config)` — SSE streaming hook
- `useChatStore` — Zustand store
