### Install and Build Claude Code CLI Provider Source: https://github.com/atalovesyou/claude-max-api-proxy/blob/main/README.md Installs project dependencies and builds the project. This is a standard Node.js project setup. ```bash git clone https://github.com/anthropics/claude-code-cli-provider.git cd claude-code-cli-provider npm install npm run build ``` -------------------------------- ### Start HTTP Server (TypeScript) Source: https://context7.com/atalovesyou/claude-max-api-proxy/llms.txt Provides TypeScript code examples for starting the Claude Code CLI Provider server using the `startServer` function. It shows how to specify ports and hosts, and handle potential errors like port conflicts. ```typescript import { startServer } from "claude-max-api-proxy"; // Start server on default port 3456 const server = await startServer({ port: 3456 }); console.log("Server running on http://127.0.0.1:3456"); // Start server on custom port and host const customServer = await startServer({ port: 8080, host: "127.0.0.1" }); // Handle port already in use error try { await startServer({ port: 3456 }); } catch (err) { if (err.message.includes("already in use")) { console.error("Port 3456 is busy, try another port"); } } ``` -------------------------------- ### Install Dependencies with npm Source: https://github.com/atalovesyou/claude-max-api-proxy/blob/main/CONTRIBUTING.md Installs all necessary project dependencies using npm. This is a prerequisite for building and running the project. ```bash npm install ``` -------------------------------- ### Install and Authenticate Claude Code CLI Source: https://github.com/atalovesyou/claude-max-api-proxy/blob/main/README.md Installs the Claude Code CLI globally using npm and logs in to authenticate with your Anthropic account. This is a prerequisite for the provider. ```bash npm install -g @anthropic-ai/claude-code claude auth login ``` -------------------------------- ### Express.js Server Setup (TypeScript) Source: https://github.com/atalovesyou/claude-max-api-proxy/blob/main/DESIGN.md This snippet illustrates the basic setup of an Express.js server for the local wrapper. It includes setting up routes and middleware for request handling and logging. ```typescript import express from 'express'; import routes from './routes'; import middleware from './middleware'; const app = express(); const port = 3456; app.use(express.json()); app.use(middleware); app.use('/v1/chat/completions', routes); app.listen(port, () => { console.log(`Wrapper server listening on port ${port}`); }); ``` -------------------------------- ### Get Node.js Version Source: https://github.com/atalovesyou/claude-max-api-proxy/blob/main/CONTRIBUTING.md Retrieves the installed Node.js version. This information is useful for reporting issues. ```bash node --version ``` -------------------------------- ### Claude Code CLI Command Example Source: https://github.com/atalovesyou/claude-max-api-proxy/blob/main/DESIGN.md This example demonstrates the command-line interface for the Claude Code CLI, specifying input/output formats, model, and session management. It relies on local credentials for authentication. ```bash claude --print --output-format stream-json --verbose \ --input-format stream-json --model \ --session-id ``` -------------------------------- ### Get Server Instance - TypeScript Source: https://context7.com/atalovesyou/claude-max-api-proxy/llms.txt Retrieves the current server instance status. If the server is not running, it attempts to start it. This function is useful for checking and managing the server's operational state. ```typescript import { startServer, getServer } from "claude-max-api-proxy"; // Check if server is running const server = getServer(); if (server) { console.log("Server is running"); } else { console.log("Server is not running"); await startServer({ port: 3456 }); } ``` -------------------------------- ### Run Server with Node.js Source: https://github.com/atalovesyou/claude-max-api-proxy/blob/main/CONTRIBUTING.md Starts the Claude Code CLI Provider server. This command executes the compiled JavaScript server file. ```bash node dist/server/standalone.js ``` -------------------------------- ### Integrate with Python OpenAI Client Source: https://context7.com/atalovesyou/claude-max-api-proxy/llms.txt Demonstrates how to use the standard OpenAI Python library to connect to the Claude Max API Proxy. It shows examples for both non-streaming and streaming chat completion requests. The client is configured with the proxy's base URL and a placeholder API key. ```python from openai import OpenAI # Initialize client pointing to local provider client = OpenAI( base_url="http://localhost:3456/v1", api_key="not-needed" # Any value works, authentication handled by CLI ) # Non-streaming request response = client.chat.completions.create( model="claude-sonnet-4", messages=[ {"role": "system", "content": "You are a helpful coding assistant."}, {"role": "user", "content": "Write a Python decorator for caching."} ], max_tokens=1000 ) print(response.choices[0].message.content) print(f"Tokens used: {response.usage.total_tokens}") # Streaming request stream = client.chat.completions.create( model="claude-opus-4", messages=[{"role": "user", "content": "Explain async/await in JavaScript."} ], stream=True ) for chunk in stream: if chunk.choices[0].delta.content: print(chunk.choices[0].delta.content, end="", flush=True) ``` -------------------------------- ### Create macOS LaunchAgent Plist for Claude Code Provider Source: https://github.com/atalovesyou/claude-max-api-proxy/blob/main/docs/macos-setup.md This bash script creates a plist file in `~/Library/LaunchAgents` to configure the Claude Code CLI Provider to run automatically on login. It specifies the program to execute, log file paths, and environment variables. Ensure to replace placeholders like `/path/to/claude-code-cli-provider` and `/Users/YOUR_USERNAME` with your actual values. ```bash cat > ~/Library/LaunchAgents/com.claude-code-provider.plist << 'PLIST' Label com.claude-code-provider Comment Claude Code CLI Provider (uses Claude Max subscription) RunAtLoad KeepAlive ProgramArguments /opt/homebrew/bin/node /path/to/claude-code-cli-provider/dist/server/standalone.js StandardOutPath /tmp/claude-provider.log StandardErrorPath /tmp/claude-provider.err.log EnvironmentVariables HOME /Users/YOUR_USERNAME PATH /Users/YOUR_USERNAME/.local/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin PLIST ``` -------------------------------- ### Configure Continue.dev to Use Claude Max Source: https://github.com/atalovesyou/claude-max-api-proxy/blob/main/README.md Example JSON configuration for Continue.dev to connect to the Claude Code CLI Provider. It specifies the provider as 'openai' and points to the local API base URL. ```json { "models": [{ "title": "Claude (Max)", "provider": "openai", "model": "claude-opus-4", "apiBase": "http://localhost:3456/v1", "apiKey": "not-needed" }] } ``` -------------------------------- ### Troubleshoot Claude Code Provider Paths and Logs Source: https://github.com/atalovesyou/claude-max-api-proxy/blob/main/docs/macos-setup.md This section provides bash commands for troubleshooting the Claude Code CLI Provider on macOS. It includes checking error logs, finding the correct paths for Node.js and the `claude` CLI, and displaying the home directory. These commands help diagnose issues like incorrect file paths or missing executables. ```bash # Check the error log cat /tmp/claude-provider.err.log ``` ```bash # Find node which node # Find claude which claude # Your home directory echo $HOME ``` -------------------------------- ### Get Claude CLI Version Source: https://github.com/atalovesyou/claude-max-api-proxy/blob/main/CONTRIBUTING.md Retrieves the installed Claude CLI version. This information is useful for reporting issues. ```bash claude --version ``` -------------------------------- ### Verify Claude CLI Installation - TypeScript Source: https://context7.com/atalovesyou/claude-max-api-proxy/llms.txt Checks if the Claude Code CLI is installed and accessible in the system's PATH. It returns an object indicating success or failure, along with the version if successful, or an error message if not found. ```typescript import { verifyClaude } from "claude-max-api-proxy"; const check = await verifyClaude(); if (check.ok) { console.log(`Claude CLI version: ${check.version}`); } else { console.error(check.error); // "Claude CLI not found. Install with: npm install -g @anthropic-ai/claude-code" } ``` -------------------------------- ### Claude CLI System Init Message (JSON) Source: https://github.com/atalovesyou/claude-max-api-proxy/blob/main/PROTOCOL.md The system init message is sent at the start of a session, providing context such as the current working directory, session ID, available tools, and model information. This message is crucial for understanding the initial state of the Claude CLI environment. ```json { "type": "system", "subtype": "init", "cwd": "/Users/atal/Desktop/ClaudeTest", "session_id": "72db4887-c10b-4445-89fa-26e4fc184df9", "tools": ["Task", "Bash", "Read", "Edit", ...], "mcp_servers": [...], "model": "claude-sonnet-4-5-20250929", "permissionMode": "bypassPermissions", "slash_commands": [...], "skills": [...], "plugins": [...], "uuid": "1121b09e-d912-4fd7-91b6-ff72a513e8e4" } ``` -------------------------------- ### Manage Claude Code Provider Service with launchctl Source: https://github.com/atalovesyou/claude-max-api-proxy/blob/main/docs/macos-setup.md These bash commands use `launchctl` to manage the Claude Code CLI Provider service on macOS. They cover loading the service, checking its status, restarting it, stopping it temporarily, and unloading it for uninstallation. Ensure the correct user ID and service label are used. ```bash # Load and start the service launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.claude-code-provider.plist # Verify it's running launchctl list | grep claude-code curl http://localhost:3456/health ``` ```bash # Check status launchctl list | grep claude-code # Restart the service launchctl kickstart -k gui/$(id -u)/com.claude-code-provider # Stop the service (temporary) launchctl bootout gui/$(id -u)/com.claude-code-provider # Start the service again launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.claude-code-provider.plist # View logs tail -f /tmp/claude-provider.log tail -f /tmp/claude-provider.err.log ``` ```bash # Stop and remove the service launchctl bootout gui/$(id -u)/com.claude-code-provider rm ~/Library/LaunchAgents/com.claude-code-provider.plist ``` -------------------------------- ### Verify Claude CLI Installation (TypeScript) Source: https://github.com/atalovesyou/claude-max-api-proxy/blob/main/DESIGN.md Checks if the Claude CLI is installed and accessible by attempting to run `claude --version`. It returns a promise indicating success or failure with an error message if not found. ```typescript import { spawn } from "child_process"; async function verifyClaude(): Promise<{ ok: boolean; error?: string }> { return new Promise((resolve) => { const proc = spawn("claude", ["--version"], { stdio: "pipe" }); proc.on("error", (err) => { resolve({ ok: false, error: "Claude CLI not found. Install with: npm install -g @anthropic-ai/claude-code" }); }); proc.on("close", (code) => { resolve({ ok: code === 0 }); }); }); } ``` -------------------------------- ### GET /v1/models Source: https://github.com/atalovesyou/claude-max-api-proxy/blob/main/DESIGN.md Retrieves a list of available models that can be used for chat completions. ```APIDOC ## GET /v1/models ### Description This endpoint returns a list of models supported by the Claude Code CLI, formatted similarly to the OpenAI API's model listing. ### Method GET ### Endpoint /v1/models ### Parameters None ### Response #### Success Response (200) - **object** (string) - Type of object, usually "list". - **data** (array) - A list of model objects. - **id** (string) - The unique identifier for the model (e.g., "claude-opus-4"). - **object** (string) - Type of object, usually "model". - **owned_by** (string) - The organization that owns the model (e.g., "anthropic"). ### Response Example ```json { "object": "list", "data": [ { "id": "claude-opus-4", "object": "model", "owned_by": "anthropic" }, { "id": "claude-sonnet-4", "object": "model", "owned_by": "anthropic" }, { "id": "claude-haiku-4", "object": "model", "owned_by": "anthropic" } ] } ``` ``` -------------------------------- ### Chat Completions (Non-Streaming) API Endpoint (Bash) Source: https://context7.com/atalovesyou/claude-max-api-proxy/llms.txt Example of making a non-streaming chat completion request to the API using curl. It sends messages in OpenAI format and receives a structured response with token usage. ```bash curl -X POST http://localhost:3456/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ \ "model": "claude-sonnet-4", \ "messages": [ \ {"role": "system", "content": "You are a helpful coding assistant."}, \ {"role": "user", "content": "Write a Python function to check if a number is prime."} ] \ }' # Response: { "id": "chatcmpl-abc123def456789012", "object": "chat.completion", "created": 1705312200, "model": "claude-sonnet-4", "choices": [ { "index": 0, "message": { "role": "assistant", "content": "def is_prime(n):\n if n < 2:\n return False for i in range(2, int(n**0.5) + 1): if n % i == 0: return False return True" }, "finish_reason": "stop" } ], "usage": { "prompt_tokens": 42, "completion_tokens": 85, "total_tokens": 127 } } ``` -------------------------------- ### Start and Stop HTTP Server using Express (TypeScript) Source: https://github.com/atalovesyou/claude-max-api-proxy/blob/main/DESIGN.md This code sets up an Express.js HTTP server to handle API requests. It includes routes for health checks, chat completions, and model listings. The server listens on a specified port and can be gracefully stopped. Dependencies include 'express' and Node.js 'http' modules. ```typescript import express from "express"; import { createServer, Server } from "http"; import { handleChatCompletions } from "./routes.js"; let server: Server | null = null; export async function startServer(port: number): Promise { const app = express(); app.use(express.json({ limit: "10mb" })); // Health check app.get("/health", (req, res) => { res.json({ status: "ok", provider: "claude-code-cli" }); }); // OpenAI-compatible endpoints app.post("/v1/chat/completions", handleChatCompletions); // Models list app.get("/v1/models", (req, res) => { res.json({ object: "list", data: [ { id: "claude-opus-4", object: "model", owned_by: "anthropic" }, { id: "claude-sonnet-4", object: "model", owned_by: "anthropic" }, { id: "claude-haiku-4", object: "model", owned_by: "anthropic" }, ], }); }); return new Promise((resolve, reject) => { server = createServer(app); server.listen(port, "127.0.0.1", () => { console.log(`Claude Code CLI server running on port ${port}`); resolve(server); }); server.on("error", reject); }); } export async function stopServer(instance: Server): Promise { return new Promise((resolve) => { instance.close(() => resolve()); }); } ``` -------------------------------- ### ClaudeSubprocess - Manage Claude CLI Processes - TypeScript Source: https://context7.com/atalovesyou/claude-max-api-proxy/llms.txt An EventEmitter-based class for managing Claude CLI subprocesses. It handles JSON stream parsing, timeouts, and graceful termination, providing events for content deltas, assistant messages, results, errors, and process closure. It allows starting and killing subprocesses, and checking their running status. ```typescript import { ClaudeSubprocess } from "claude-max-api-proxy"; const subprocess = new ClaudeSubprocess(); // Listen for streaming content deltas subprocess.on("content_delta", (event) => { const text = event.event.delta?.text || ""; process.stdout.write(text); }); // Listen for final assistant message (includes model info) subprocess.on("assistant", (message) => { console.log(`\nModel: ${message.message.model}`); console.log(`Tokens: ${message.message.usage.output_tokens}`); }); // Listen for final result subprocess.on("result", (result) => { console.log(`\nFinal result: ${result.result}`); console.log(`Duration: ${result.duration_ms}ms`); console.log(`Total cost: $${result.total_cost_usd}`); }); // Handle errors subprocess.on("error", (error) => { console.error("Subprocess error:", error.message); }); // Handle process close subprocess.on("close", (code) => { console.log(`Process exited with code: ${code}`); }); // Start the subprocess with prompt and options await subprocess.start("Explain the difference between let and const in JavaScript", { model: "sonnet", // "opus" | "sonnet" | "haiku" sessionId: "user-123", // Optional session ID for context timeout: 300000, // Optional timeout in ms (default: 5 minutes) cwd: "/path/to/project" // Optional working directory }); // Kill subprocess if needed (e.g., client disconnect) subprocess.kill("SIGTERM"); // Check if still running if (subprocess.isRunning()) { console.log("Still processing..."); } ``` -------------------------------- ### Build Project with npm Source: https://github.com/atalovesyou/claude-max-api-proxy/blob/main/CONTRIBUTING.md Builds the project using npm scripts. This command compiles the TypeScript code and prepares the project for execution. ```bash npm run build ``` -------------------------------- ### GET /health Source: https://github.com/atalovesyou/claude-max-api-proxy/blob/main/DESIGN.md A health check endpoint to verify if the server is running and responsive. ```APIDOC ## GET /health ### Description Provides a simple health check to confirm the API server is operational. ### Method GET ### Endpoint /health ### Parameters None ### Response #### Success Response (200) - **status** (string) - Indicates the health status, typically "ok". - **provider** (string) - The provider of the service, "claude-code-cli". ### Response Example ```json { "status": "ok", "provider": "claude-code-cli" } ``` ``` -------------------------------- ### Check Claude CLI Path (Bash) Source: https://github.com/atalovesyou/claude-max-api-proxy/blob/main/README.md This command helps troubleshoot server startup issues by verifying if the Claude CLI executable is present in the system's PATH environment variable. If 'Claude CLI not found' errors occur, this command can confirm its accessibility. ```bash which claude ``` -------------------------------- ### Plugin API Methods (JavaScript) Source: https://github.com/atalovesyou/claude-max-api-proxy/blob/main/ARCHITECTURE.md Outlines the methods available through the Plugin API, provided by `plugins/registry.js`. These methods allow plugins to register various components like tools, hooks, HTTP handlers, and more. ```javascript interface PluginApi { id: string; name: string; version: string; config: Config; runtime: Runtime; logger: Logger; // Registration methods registerTool(tool, opts?): void; registerHook(events, handler, opts?): void; registerHttpHandler(handler): void; registerChannel(registration): void; registerProvider(provider): void; // For model providers registerGatewayMethod(method, handler): void; registerCli(registrar, opts?): void; registerService(service): void; registerCommand(command): void; // Utilities resolvePath(input): string; on(hookName, handler, opts?): void; } ``` -------------------------------- ### Error Handling Source: https://github.com/atalovesyou/claude-max-api-proxy/blob/main/DESIGN.md Details on how various edge cases and errors are handled, including Claude CLI installation issues, token expiration, timeouts, and rate limits. ```APIDOC ## Edge Cases & Error Handling This section describes how the system handles potential issues and edge cases during operation. ### 1. Claude CLI Not Installed The system checks for the presence of the Claude CLI using `child_process.spawn()`. If the command is not found, an informative error message is provided to the user, guiding them on how to install it. **Verification Logic:** ```typescript import { spawn } from "child_process"; async function verifyClaude(): Promise<{ ok: boolean; error?: string }> { return new Promise((resolve) => { const proc = spawn("claude", ["--version"], { stdio: "pipe" }); proc.on("error", (err) => { resolve({ ok: false, error: "Claude CLI not found. Install with: npm install -g @anthropic-ai/claude-code" }); }); proc.on("close", (code) => { resolve({ ok: code === 0 }); }); }); } ``` ### 2. OAuth Token Expired - **Automatic Refresh**: The Claude CLI is designed to handle OAuth token refresh automatically. - **Manual Intervention**: If authentication persistently fails, users are prompted to run `claude auth login` to re-authenticate. ### 3. Subprocess Timeout To prevent indefinite hangs, subprocesses are configured with a timeout. If a subprocess exceeds the defined `TIMEOUT_MS` (e.g., 5 minutes), it will be terminated, and an error will be raised. **Timeout Implementation:** ```typescript const TIMEOUT_MS = 300000; // 5 minutes setTimeout(() => { subprocess.kill(); reject(new Error("Request timed out")); }, TIMEOUT_MS); ``` ### 4. Concurrent Request Limits - **Rate Limiting**: The Claude Max API may enforce rate limits on concurrent requests. - **Concurrency Control**: To manage this, a request queue mechanism is implemented, allowing for configurable concurrency levels to avoid exceeding these limits. ``` -------------------------------- ### Use Claude Max with Generic OpenAI Client (Python) Source: https://github.com/atalovesyou/claude-max-api-proxy/blob/main/README.md Python code snippet demonstrating how to use the OpenAI Python client to interact with the Claude Code CLI Provider. It configures the client with the local API base URL. ```python from openai import OpenAI client = OpenAI( base_url="http://localhost:3456/v1", api_key="not-needed" # Any value works ) response = client.chat.completions.create( model="claude-opus-4", messages=[{"role": "user", "content": "Hello!"}] ) ``` -------------------------------- ### Configure Continue.dev IDE Extension Source: https://context7.com/atalovesyou/claude-max-api-proxy/llms.txt Provides the JSON configuration for the Continue IDE extension to integrate with Claude Max API models. It specifies model details like title, provider, model name, API base URL, and API key for both chat completion and tab autocomplete functionalities. ```json { "models": [ { "title": "Claude Opus (Max)", "provider": "openai", "model": "claude-opus-4", "apiBase": "http://localhost:3456/v1", "apiKey": "local" }, { "title": "Claude Sonnet (Max)", "provider": "openai", "model": "claude-sonnet-4", "apiBase": "http://localhost:3456/v1", "apiKey": "local" } ], "tabAutocompleteModel": { "title": "Claude Haiku (Max)", "provider": "openai", "model": "claude-haiku-4", "apiBase": "http://localhost:3456/v1", "apiKey": "local" } } ``` -------------------------------- ### Register Claude Code CLI Provider (index.ts) Source: https://github.com/atalovesyou/claude-max-api-proxy/blob/main/DESIGN.md Registers the Claude Code CLI provider with the plugin SDK. This function starts a local HTTP server, configures authentication, and defines available models and their properties. It also handles server cleanup when the plugin is unloaded. ```typescript import { emptyPluginConfigSchema } from "clawdbot/plugin-sdk"; import { startServer, stopServer } from "./server/index.js"; const PROVIDER_ID = "claude-code-cli"; const DEFAULT_PORT = 3456; const DEFAULT_MODEL = "claude-code-cli/claude-sonnet-4"; const AVAILABLE_MODELS = [ { id: "claude-opus-4", name: "Claude Opus 4.5", alias: "opus" }, { id: "claude-sonnet-4", name: "Claude Sonnet 4", alias: "sonnet" }, { id: "claude-haiku-4", name: "Claude Haiku 4", alias: "haiku" }, ]; const plugin = { id: "claude-code-cli", name: "Claude Code CLI Provider", description: "Use Claude Max subscription via Claude Code CLI", configSchema: emptyPluginConfigSchema(), register(api) { // Start the local HTTP server when plugin loads let serverInstance = null; api.registerProvider({ id: PROVIDER_ID, label: "Claude Code CLI", docsPath: "/providers/claude-code-cli", aliases: ["claude-cli", "claude-max"], auth: [{ id: "local", label: "Local Claude CLI", hint: "Uses your existing Claude Code CLI authentication", kind: "custom", run: async (ctx) => { const spin = ctx.prompter.progress("Checking Claude CLI..."); // 1. Verify claude CLI is installed and authenticated const cliCheck = await verifyClaude(); if (!cliCheck.ok) { spin.stop("Claude CLI not found"); throw new Error(cliCheck.error); } // 2. Start local server if not running const port = await ctx.prompter.text({ message: "Local server port", initialValue: String(DEFAULT_PORT), validate: (v) => isNaN(parseInt(v)) ? "Enter a valid port" : undefined, }); serverInstance = await startServer(parseInt(port)); spin.stop("Claude CLI provider ready"); const baseUrl = `http://localhost:${port}/v1`; return { profiles: [{ profileId: `${PROVIDER_ID}:local`, credential: { type: "token", provider: PROVIDER_ID, token: "local", // Dummy token, CLI handles auth }, }], configPatch: { models: { providers: { [PROVIDER_ID]: { baseUrl, apiKey: "local", api: "openai-completions", authHeader: false, models: AVAILABLE_MODELS.map(m => ({ id: m.id, name: m.name, api: "openai-completions", reasoning: m.id.includes("opus"), input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 200000, maxTokens: 8192, })), }, }, }, agents: { defaults: { models: Object.fromEntries( AVAILABLE_MODELS.map(m => [`${PROVIDER_ID}/${m.id}`, {}]) ), }, }, }, defaultModel: DEFAULT_MODEL, notes: [ "This uses your Claude Max subscription via Claude Code CLI.", "Make sure you're logged into Claude Code (`claude auth login`).", `Local server running at http://localhost:${port}`, ], }; }, }], }); // Cleanup on plugin unload api.on("plugin:unload", async () => { if (serverInstance) { await stopServer(serverInstance); } }); }, }; export default plugin; ``` -------------------------------- ### Manage Conversation Sessions (TypeScript) Source: https://context7.com/atalovesyou/claude-max-api-proxy/llms.txt Manages a singleton mapping of external conversation IDs to Claude CLI session UUIDs, enabling context persistence across requests. Sessions automatically expire after 24 hours and are cleaned up periodically. It provides methods to get, create, delete, and list active sessions. ```typescript import { sessionManager } from "claude-max-api-proxy"; // Initialize (automatically called on import) await sessionManager.load(); // Get or create a session ID for a conversation const claudeSessionId = sessionManager.getOrCreate("telegram-chat-12345", "sonnet"); console.log(claudeSessionId); // "550e8400-e29b-41d4-a716-446655440000" // Get existing session without creating const existing = sessionManager.get("telegram-chat-12345"); if (existing) { console.log(`Session created: ${new Date(existing.createdAt)}`); console.log(`Last used: ${new Date(existing.lastUsedAt)}`); console.log(`Model: ${existing.model}`); } // Delete a session (e.g., user ends conversation) sessionManager.delete("telegram-chat-12345"); // Clean up expired sessions (called automatically every hour) const removedCount = sessionManager.cleanup(); console.log(`Removed ${removedCount} expired sessions`); // Get all active sessions const allSessions = sessionManager.getAll(); console.log(`Active sessions: ${sessionManager.size}`); ``` -------------------------------- ### List Models API Endpoint (Bash) Source: https://context7.com/atalovesyou/claude-max-api-proxy/llms.txt Shows how to retrieve a list of available Claude models in an OpenAI-compatible format using curl. This is useful for model discovery and selection. ```bash curl http://localhost:3456/v1/models # Response: { "object": "list", "data": [ { "id": "claude-opus-4", "object": "model", "owned_by": "anthropic", "created": 1705312200 }, { "id": "claude-sonnet-4", "object": "model", "owned_by": "anthropic", "created": 1705312200 }, { "id": "claude-haiku-4", "object": "model", "owned_by": "anthropic", "created": 1705312200 } ] } ``` -------------------------------- ### Authentication Method Interface (TypeScript) Source: https://github.com/atalovesyou/claude-max-api-proxy/blob/main/ARCHITECTURE.md Defines the structure for individual authentication methods within a provider. This includes the method's ID, label, help text, kind (e.g., 'oauth', 'api_key'), and a function to run the authentication process. ```typescript interface AuthMethod { id: string; // Method ID (e.g., "oauth", "local") label: string; // Display label hint: string; // Help text kind: "oauth" | "custom" | "api_key"; run: async (ctx: AuthContext) => AuthResult; } ``` -------------------------------- ### Chat Completions (Streaming) API Endpoint (Bash) Source: https://context7.com/atalovesyou/claude-max-api-proxy/llms.txt Demonstrates how to initiate a streaming chat completion request using curl with the `stream: true` option. Responses are received as a Server-Sent Events (SSE) stream. ```bash curl -N -X POST http://localhost:3456/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ \ "model": "claude-opus-4", \ "messages": [{"role": "user", "content": "Explain recursion briefly."}], "stream": true }' # Response (SSE stream): :ok data: {"id":"chatcmpl-abc123","object":"chat.completion.chunk","created":1705312200,"model":"claude-opus-4","choices":[{"index":0,"delta":{"role":"assistant","content":"Recursion"},"finish_reason":null}]} data: {"id":"chatcmpl-abc123","object":"chat.completion.chunk","created":1705312200,"model":"claude-opus-4","choices":[{"index":0,"delta":{"content":" is when"},"finish_reason":null}]} data: {"id":"chatcmpl-abc123","object":"chat.completion.chunk","created":1705312200,"model":"claude-opus-4","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]} data: [DONE] ``` -------------------------------- ### List Models API Source: https://github.com/atalovesyou/claude-max-api-proxy/blob/main/README.md Retrieves a list of all available Claude models that can be used through this provider. ```APIDOC ## GET /v1/models ### Description Lists all the AI models supported by the Claude Code CLI Provider. ### Method GET ### Endpoint /v1/models ### Parameters None ### Request Example None ### Response #### Success Response (200) - **data** (array) - An array of model objects. - **id** (string) - The unique identifier for the model (e.g., `claude-opus-4`). - **object** (string) - The type of object, typically "model". - **owned_by** (string) - The entity that owns the model, usually "anthropic". #### Response Example ```json { "data": [ { "id": "claude-opus-4", "object": "model", "owned_by": "anthropic" }, { "id": "claude-sonnet-4", "object": "model", "owned_by": "anthropic" }, { "id": "claude-haiku-4", "object": "model", "owned_by": "anthropic" } ] } ``` ``` -------------------------------- ### Authentication Profile Interface (TypeScript) Source: https://github.com/atalovesyou/claude-max-api-proxy/blob/main/ARCHITECTURE.md Defines the structure for an individual authentication profile. This includes a unique profile ID and the credential details, specifying the type and provider, along with type-specific fields. ```typescript interface AuthProfile { profileId: string; // e.g., "claude-code-cli:max" credential: { type: "oauth" | "token" | "api_key"; provider: string; // Type-specific fields (access, refresh, token, apiKey, etc.) }; } ``` -------------------------------- ### Node.js/TypeScript: Chat Completions with Native Fetch Source: https://context7.com/atalovesyou/claude-max-api-proxy/llms.txt This snippet demonstrates how to perform a standard chat completion request to the Claude Max API Proxy using Node.js and TypeScript's native fetch API. It sends a user prompt and retrieves a single response. Ensure the proxy is running locally on port 3456. ```typescript async function chat(prompt: string): Promise { const response = await fetch("http://localhost:3456/v1/chat/completions", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ model: "claude-sonnet-4", messages: [{ role: "user", content: prompt }] }) }); const data = await response.json(); return data.choices[0].message.content; } // Usage const answer = await chat("What is the capital of France?"); console.log(answer); ``` -------------------------------- ### Claude CLI System Hook Messages (JSON) Source: https://github.com/atalovesyou/claude-max-api-proxy/blob/main/PROTOCOL.md Hook messages indicate the status of internal hooks within the Claude CLI. `hook_started` signifies the beginning of a hook execution, while `hook_response` provides the outcome, including output and exit code. These are useful for monitoring and debugging CLI processes. ```json { "type": "system", "subtype": "hook_started", "hook_id": "...", "hook_name": "SessionStart:startup", "hook_event": "SessionStart", "session_id": "..." } ``` ```json { "type": "system", "subtype": "hook_response", "hook_id": "...", "output": "...", "exit_code": 0, "outcome": "success" } ``` -------------------------------- ### Test Claude Code CLI Provider API Endpoints Source: https://github.com/atalovesyou/claude-max-api-proxy/blob/main/README.md Demonstrates how to test the provider's API endpoints using curl. Includes health check, listing models, and chat completion requests (both streaming and non-streaming). ```bash # Health check curl http://localhost:3456/health # List models curl http://localhost:3456/v1/models # Chat completion (non-streaming) curl -X POST http://localhost:3456/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "claude-opus-4", "messages": [{"role": "user", "content": "Hello!"}] }' # Chat completion (streaming) curl -N -X POST http://localhost:3456/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "claude-opus-4", "messages": [{"role": "user", "content": "Hello!"}], "stream": true }' ``` -------------------------------- ### Provider Interface Definition (TypeScript) Source: https://github.com/atalovesyou/claude-max-api-proxy/blob/main/ARCHITECTURE.md Defines the structure for authentication providers in Clawdbot. It includes provider identification, display labels, documentation paths, aliases, environment variables, and an array of authentication methods. ```typescript interface Provider { id: string; // Provider ID (e.g., "claude-code-cli") label: string; // Display name docsPath?: string; // Documentation path aliases?: string[]; // Alternative names envVars?: string[]; // Related environment variables auth: AuthMethod[]; // Authentication methods } ``` -------------------------------- ### Chat Completions (Streaming) Source: https://context7.com/atalovesyou/claude-max-api-proxy/llms.txt Handles chat completion requests with real-time token streaming via Server-Sent Events (SSE). ```APIDOC ## POST /v1/chat/completions?stream=true ### Description Real-time token streaming via Server-Sent Events (SSE) for interactive applications. Use `-N` flag with curl to disable buffering. ### Method POST ### Endpoint /v1/chat/completions ### Parameters #### Path Parameters None #### Query Parameters - **stream** (boolean) - Required - Set to `true` to enable streaming responses. #### Request Body - **model** (string) - Required - The ID of the model to use for completion (e.g., "claude-opus-4"). - **messages** (array) - Required - A list of message objects representing the conversation history. - **role** (string) - Required - The role of the author of the message ("system", "user", or "assistant"). - **content** (string) - Required - The content of the message. - **temperature** (number) - Optional - Controls randomness. Lower values make output more deterministic. - **max_tokens** (integer) - Optional - The maximum number of tokens to generate in the completion. ### Request Example ```bash curl -N -X POST http://localhost:3456/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "claude-opus-4", "messages": [{"role": "user", "content": "Explain recursion briefly." }], "stream": true }' ``` ### Response #### Success Response (200) Responses are streamed as Server-Sent Events (SSE). - **data: ...** - Each chunk of the completion is sent as a JSON object prefixed with `data: `. - **id** (string) - Unique identifier for the completion. - **object** (string) - The type of object, "chat.completion.chunk". - **created** (integer) - Unix timestamp of creation. - **model** (string) - The model used for the completion. - **choices** (array) - A list of completion choices. - **index** (integer) - Index of the choice. - **delta** (object) - The partial message content. - **role** (string) - The role of the assistant (only in the first chunk). - **content** (string) - The content of the assistant's message chunk. - **finish_reason** (string) - The reason the model stopped generating tokens (null until the final chunk). - **data: [DONE]** - Indicates the end of the stream. #### Response Example (SSE stream): ``` :ok data: {"id":"chatcmpl-abc123","object":"chat.completion.chunk","created":1705312200,"model":"claude-opus-4","choices":[{"index":0,"delta":{"role":"assistant","content":"Recursion"},"finish_reason":null}]} data: {"id":"chatcmpl-abc123","object":"chat.completion.chunk","created":1705312200,"model":"claude-opus-4","choices":[{"index":0,"delta":{"content":" is when"},"finish_reason":null}]} data: {"id":"chatcmpl-abc123","object":"chat.completion.chunk","created":1705312200,"model":"claude-opus-4","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]} data: [DONE] ``` ``` -------------------------------- ### Plugin Interface Definition (TypeScript) Source: https://github.com/atalovesyou/claude-max-api-proxy/blob/main/ARCHITECTURE.md Defines the structure for plugins in Clawdbot, including their ID, name, description, configuration schema, and registration function. This interface ensures consistency for all registered plugins. ```typescript interface Plugin { id: string; // Unique plugin ID name: string; // Display name description: string; // Plugin description configSchema: Schema; // Configuration schema (use emptyPluginConfigSchema()) register(api: PluginApi): void; // Registration function } ``` -------------------------------- ### Claude CLI Flags for Programmatic Use Source: https://github.com/atalovesyou/claude-max-api-proxy/blob/main/PROTOCOL.md These bash commands configure the Claude CLI for non-interactive, programmatic use, enabling JSON streaming for input and output. Key flags control output format, verbosity, session management, and model selection. Ensure `--verbose` is used with `--output-format stream-json`. ```bash claude --print \ --output-format stream-json \ --input-format stream-json \ --verbose \ --include-partial-messages \ --model \ --session-id \ --resume ``` -------------------------------- ### Authentication Result Interface (TypeScript) Source: https://github.com/atalovesyou/claude-max-api-proxy/blob/main/ARCHITECTURE.md Defines the structure of the result returned by an authentication method. It includes a list of authentication profiles, an optional configuration patch, a default model, and informational notes. ```typescript interface AuthResult { profiles: AuthProfile[]; configPatch?: ConfigPatch; // Config to merge defaultModel?: string; notes?: string[]; } ``` -------------------------------- ### Manage Claude Subprocess with spawn() in TypeScript Source: https://github.com/atalovesyou/claude-max-api-proxy/blob/main/DESIGN.md Manages the lifecycle of a child process for interacting with the Claude CLI. It uses `spawn()` for security, preventing command injection. The subprocess takes a prompt and model configuration, sending input via stdin and parsing JSON output from stdout. It emits events for messages, errors, and process closure. ```typescript import { spawn, ChildProcess } from "child_process"; import { EventEmitter } from "events"; import { ClaudeCliMessage, ClaudeCliResult } from "../types/claude-cli.js"; interface SubprocessOptions { model: "opus" | "sonnet" | "haiku"; sessionId?: string; cwd?: string; } export class ClaudeSubprocess extends EventEmitter { private process: ChildProcess | null = null; private buffer: string = ""; async start(prompt: string, options: SubprocessOptions): Promise { const args = [ "--print", "--output-format", "stream-json", "--input-format", "stream-json", "--verbose", "--model", options.model, ]; if (options.sessionId) { args.push("--session-id", options.sessionId); } // Don't persist sessions for stateless API usage args.push("--no-session-persistence"); // Use spawn() for security - no shell interpretation this.process = spawn("claude", args, { cwd: options.cwd || process.cwd(), env: { ...process.env }, stdio: ["pipe", "pipe", "pipe"], }); // Send the prompt via stdin this.process.stdin?.write(JSON.stringify({ type: "user_message", content: prompt, }) + "\n"); this.process.stdin?.end(); // Parse JSON stream from stdout this.process.stdout?.on("data", (chunk) => { this.buffer += chunk.toString(); this.processBuffer(); }); this.process.stderr?.on("data", (chunk) => { this.emit("error", new Error(chunk.toString())); }); this.process.on("close", (code) => { this.emit("close", code); }); } private processBuffer(): void { const lines = this.buffer.split("\n"); this.buffer = lines.pop() || ""; // Keep incomplete line for (const line of lines) { if (!line.trim()) continue; try { const message: ClaudeCliMessage = JSON.parse(line); this.emit("message", message); if (message.type === "assistant") { this.emit("assistant", message); } else if (message.type === "result") { this.emit("result", message as ClaudeCliResult); } } catch (e) { // Non-JSON output, emit as raw this.emit("raw", line); } } } kill(): void { this.process?.kill(); } } ```