Reviewer found a third instance, and it is the one that most directly reproduces #136.
README has two forms of the same LAN-mode install: the copy-paste AI prompt (line 132) and
the handbook form (line 218). Line 180 explicitly asserts they are 'the same steps in handbook
form'. They were not:
line 132 (prompt) 'install OCP as a server so YOUR OWN DEVICES on the LAN can reach it
(Claude Pro/Max are per-user accounts — review Anthropic's Usage Policy
before extending access to other people)' + example keys: laptop, tablet
line 218 (handbook) 'share with other devices on your network:' + 'create API keys for each
PERSON/device' + no ToS pointer at all
So a reader who takes the manual route instead of the copy-paste route is still walked into
per-person key creation with zero ToS mention — reproducing #136's trigger through the door
the first commit did not close. The caveat now matches its twin.
Deliberately NOT scrubbing the wife-laptop / son-ipad example key names: they recur in seven
further places, it is a bigger diff at a different severity, and it edges into scrubbing the
maintainer's household out of their own documentation. With the pointer restored at 218 those
examples inherit the caveat — which is exactly the posture § honest limits takes. It never
forbids family sharing; it says it is the account holder's call and their risk, and refuses to
hide that.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VqgWJcjxrjjL9L9SkpZyXR
Independent reviewer caught two things in the first cut:
1. The new link pointed at #auth-modes — which resolves to the '### Auth Modes' mode
table (line 408), NOT to the 'Sharing with family / a team — honest limits'
paragraph (line 422), which sits under '### Deployment model & security (read
this)' (line 418). A bullet that says 'see the honest limits' and then sends you
somewhere else is worse than no link. Correct anchor verified two ways (github-slugger
+ the live rendered page): #deployment-model--security-read-this (double hyphen — the
'&' is stripped but both surrounding spaces survive).
2. Line 52 carried the SAME defect the PR was written to fix, a few lines below it:
'share one Claude Pro/Max subscription across IDEs, devices, and people'. So the
original claim — 'this only stops the document arguing with itself' — was not yet
true: it stopped one instance and left an adjacent one standing, in the same
top-of-README section an install-time reviewer reads first.
Left alone deliberately: the maintainer's own account of their household's use (lines 7
and 1178). That is theirs to make, and a docs PR should not quietly rewrite it.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VqgWJcjxrjjL9L9SkpZyXR
Issue #136: an external user reported that Claude Code REFUSES to run OCP's own
copy-paste install prompt, on the grounds that the premise — pooling one Pro/Max
subscription across a family — violates Anthropic's Usage Policy.
The install prompts themselves were already fixed since that report ('my own devices
on the network', plus a ToS warning on the LAN section). What remained was a
self-contradiction in the README:
line 27 (feature bullet): 'share one Claude Pro/Max subscription with family,
friends, or your own devices'
line 427 (§ honest limits): 'The defensible framing is "one person, your own
devices" — sharing with friends or a team is not.'
The top-of-funnel bullet was promoting exactly what the project's own ToS section
calls indefensible. That is a defect on its own terms, independent of anyone's view
on the underlying policy: a reader who trusts the bullet is walked straight into the
thing the same document later tells them not to do.
Aligned the bullet to the position the project ALREADY took, and linked the honest-limits
section from it. No change to the auth modes, the LAN feature, or the maintainer's own
account of how they use it — this only stops the doc arguing with itself.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VqgWJcjxrjjL9L9SkpZyXR
Removed v3.0.x migration guide, old idleTimeoutSeconds workaround
(auto-handled by setup.mjs since v3.2.1), and manual session cleanup
instructions. Replaced with concise troubleshooting for common issues.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ocp-connect now detects installed IDEs and offers to configure them
automatically. OpenClaw gets full interactive setup (provider name,
primary/backup priority, model aliases). Other IDEs (Cline, Continue.dev,
Cursor) get manual config instructions printed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Writes to both .bashrc and .zshrc on macOS (covers both shells)
- macOS: launchctl setenv for GUI apps and daemons
- Linux: ~/.config/environment.d/ocp.conf for systemd user services
- Ensures IDEs and daemons can discover OCP models
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When the /api/oauth/usage endpoint returns 429 (rate limit), fall back
to the most recent cached data instead of returning an error. Also
extended cache TTL from 5min to 15min to reduce API calls.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds CLAUDE_NO_CONTEXT=true env var that passes
CLAUDE_CODE_DISABLE_CLAUDE_MDS=1 and CLAUDE_CODE_DISABLE_AUTO_MEMORY=1
to Claude CLI child processes. This suppresses CLAUDE.md and auto-memory
injection while preserving OAuth auth — needed for third-party agents
like Hermes that have their own memory systems.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
In zero-config auth mode, the server allows anonymous access even in
multi mode. The script now probes /v1/models first — if it succeeds,
no key is needed. Also updated README examples and version to 3.5.1.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replaces the old approach (sending a real messages API request just to
read rate-limit headers) with the dedicated usage endpoint that Claude
Code CLI uses. Fixes intermittent "unknown" plan usage.
- GET /api/oauth/usage with Bearer auth + anthropic-beta header
- Auto-refresh expired OAuth tokens via refresh_token grant
- Try both keychain label formats (claude-code-credentials, Claude Code-credentials)
- Zero API quota consumption for usage checks
- Parse new JSON response format (five_hour/seven_day structure)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Multi mode now allows unauthenticated requests as "anonymous".
Keys are optional: provide one for per-key usage tracking, or
skip it for zero-config access. Invalid keys are still rejected.
Localhost requests are always admin-level (can manage keys,
view dashboard data, etc.) without any token.
This makes OCP much friendlier for home LAN setups — family
members can use it immediately without any key configuration.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Requests from 127.0.0.1/::1 skip authentication even in multi/shared
auth modes. Only remote (LAN) clients need API keys.
This simplifies local tool integration — IDEs and agents on the same
machine no longer need to configure Bearer tokens.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Support ?token=xxx query parameter for dashboard auth (enables
headless browser screenshots and direct links)
- Token is saved to localStorage and URL is cleaned up
- Fix pathname matching to handle query parameters in URL
- Replace html2canvas screenshot with Playwright (accurate colors)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Clarify that /ocp commands are for Telegram/Discord via gateway plugin,
while terminal CLI uses ocp (without slash).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add LAN mode to share one Claude Pro/Max subscription across a household:
- 3-tier auth: none / shared / multi (per-user API keys)
- SQLite-backed key management and per-request usage tracking
- Embedded web dashboard with real-time monitoring
- CLI commands: keys, lan, usage --by-key
- Zero external dependencies (uses node:sqlite)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add LAN CLI commands (keys, lan, usage --by-key), new API endpoints
(dashboard, keys, usage), LAN env vars (CLAUDE_BIND, CLAUDE_AUTH_MODE,
OCP_ADMIN_KEY), and expanded security section.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add _curl wrapper that reads OCP_ADMIN_KEY env or ~/.ocp/admin-key file
- All admin API calls (keys, usage) use _curl for auth
- Fix ocp lan IP detection to try en0 and en1
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
better-sqlite3 native addon fails on Node v25. Node.js built-in SQLite
(node:sqlite) has an identical synchronous API and requires no compilation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix 1 (keys.mjs): listKeys() no longer leaks full API key field in response
- Fix 2 (server.mjs): Remove BIND_ADDRESS admin bypass from isAdmin check
- Fix 3 (server.mjs): Admin key comparison now uses timingSafeEqual
- Fix 4 (server.mjs): Cap limit (max 500) and hours (max 720) in GET /api/usage
- Fix 5 (server.mjs): Streaming error path now computes promptChars from messages
- Fix 6 (server.mjs): Warn at startup if AUTH_MODE=shared but PROXY_API_KEY is empty
- Fix 7 (server.mjs): All recordUsage calls wrapped in try/catch to prevent DB errors crashing server
- Fix 8 (server.mjs): CORS fallback changed from "*" to specific origin (http://127.0.0.1:<PORT>)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
setup.mjs now resolves /opt/homebrew/Cellar/node/X.Y.Z/ to
/opt/homebrew/opt/node/ so the LaunchAgent plist survives node upgrades.
Bump to v3.3.1.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove firstByteTimeout, adaptive tier algorithm, and MODEL_TIMEOUT_TIERS.
Claude tool-use causes 30s-5min pauses in token streams, making fine-grained
timeouts unreliable — they repeatedly killed valid requests. A single generous
timeout (10 min, matching LiteLLM/OpenAI SDK defaults) is simpler and correct.
Breaking: CLAUDE_FIRST_BYTE_TIMEOUT env var removed, default timeout changed
from 300s to 600s. Bump to v3.3.0.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The adaptive timeout calculation ignored BASE_FIRST_BYTE_TIMEOUT (set via
CLAUDE_FIRST_BYTE_TIMEOUT env), always using the tier base (120s for Sonnet).
Now uses whichever is larger: adaptive or env override. Bump to v3.2.2.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
setup.mjs now sets agents.defaults.llm.idleTimeoutSeconds=0 in
openclaw.json during installation. Without this, OpenClaw's default
60s idle timeout kills Claude connections during tool use (Bash, Read,
etc.), causing exit 143 errors and stuck sessions.
Also adds troubleshooting section to README. Bump to v3.2.1.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
BASH_SOURCE returns the symlink path, not the target. This broke
ocp update on systems where ocp is installed as a symlink
(e.g. ~/.local/bin/ocp → repo/ocp).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- `ocp update`: pulls latest from GitHub, syncs plugin, restarts proxy
- `ocp update --check`: shows current vs latest version without applying
- `ocp restart`: now handles both dev.ocp.proxy and legacy ai.openclaw.proxy
service names on macOS/Linux
- Bumps to v3.2.0
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
OpenClaw's gateway scans LaunchAgent plists and systemd units for
"openclaw" markers and flags them as conflicting gateway-like services.
Renamed service identifiers to avoid false positives:
- macOS: ai.openclaw.proxy → dev.ocp.proxy
- Linux: openclaw-proxy.service → ocp-proxy.service
- Logs: ~/.openclaw/logs/ → ~/.ocp/logs/
Setup auto-removes legacy service names on upgrade. Uninstall handles
both old and new names. Also bumps version to 3.1.0.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Renamed from OpenClaw Control Plane to Open Claude Proxy. README
rewritten to position OCP as a universal proxy for any IDE that
speaks the OpenAI protocol, not just OpenClaw.
Added: supported tools table (Cline, OpenCode, Aider, Continue.dev),
simplified Quick Start, architecture diagram showing multi-IDE flow.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Documented the intermittent "Unknown skill: ocp" issue caused by
OpenClaw gateway session routing bug (#26895). Workaround: /new
followed by /ocp restart.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The slash session workaround was incomplete — root cause still under
investigation. Removed to avoid misleading users. Will add back with
accurate info once the issue is fully resolved.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New subcommands:
- /ocp restart [gateway|all] — restart proxy, gateway, or both
- /ocp version — show version, uptime, platform info
- /ocp test — end-to-end proxy test (sends haiku request)
- /ocp backends — list registered backends with health status
Also includes clean-slash-sessions.sh workaround for OpenClaw #26895.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Document OpenClaw gateway bug (#26895, #54485) where telegram:slash
sessions interfere with registerCommand plugin routing. Include
workaround script and warning not to add ocp to agent skills lists.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
On Linux (no macOS keychain), read ~/.claude/.credentials.json first.
Falls through to macOS keychain if file not found. Fixes /ocp usage
showing "No OAuth token" on Linux servers and RPi.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Common issue: ocp not in PATH after clone. Added explicit symlink
instructions with absolute paths and a troubleshooting note.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- README: add "Status: Stable" badge, rename title to OCP — OpenClaw Control Plane
- package.json: update description and repo URL to dtzp555-max/ocp
- No code changes. Feature-complete, bug fixes only going forward.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Reverts b5be1c0 and 1f1b387. These changes broke the OAuth token
authentication for fetching plan usage data from Anthropic API,
causing /ocp usage to show 0% with "unknown" reset times.
Root cause: code changes inadvertently altered the fetchUsageFromApi
flow, breaking the existing working OAuth x-api-key authentication.
This restores server.mjs to the last known working state (f6f4f68).
Phase 1 modular files removed — will be re-implemented in a separate
branch with proper isolation testing.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When the Claude Code OAuth token expires, /ocp usage showed 0% for all
plan limits. OCP now detects expiry and triggers a refresh via Claude CLI,
then re-reads the updated token from keychain. The 5-minute usage cache
prevents excessive refresh attempts.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Explains removing old skills/ocp/SKILL.md to avoid conflict
with the new plugin-based command handler.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Document the 2026-03-22 multi-agent cascading timeout incident, root cause
analysis, and all new/changed defaults. Update env vars table.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Emergency fix for multi-agent (ClawTeam) burst scenario that caused cascading
failures: when multiple Opus agents ran concurrently, the old consecutive-count
breaker (threshold=3) tripped within seconds, blocking ALL subsequent requests
globally — including non-ClawTeam agents and new sessions.
Changes:
- Circuit breaker now uses a sliding time window (default 5min) instead of
consecutive failure count. 6 failures in 5min triggers open, vs old 3-in-a-row.
- Half-open state allows 2 concurrent probe requests (was 1), improving recovery
speed when API comes back.
- Graduated backoff: cooldown doubles on each re-open (120s→240s→300s cap),
resets fully on first success.
- Increased default timeouts: Opus first-byte 60s→90s, Sonnet 45s→60s,
overall 120s→300s, max concurrent 5→8.
- /health endpoint now exposes per-model breaker state, window stats, and
marks status as "degraded" when any breaker is open.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Circuit breaker: consecutive timeouts (default 3) mark model as degraded for 60s,
failing fast instead of blocking gateway with repeated timeout attempts
- Per-model timeout tiers: Opus 60s base, Sonnet 45s, Haiku 30s, plus adaptive
scaling by prompt size (~15s/100k chars for Opus)
- Structured JSON logging for spawns, timeouts, breaker state changes
- Late close guard: prevents double-settle when timeout fires before proc.close
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Reduced default CLAUDE_TIMEOUT from 300s to 120s for faster fallback
- Added CLAUDE_FIRST_BYTE_TIMEOUT (default 30s): aborts early if Claude
CLI produces no output, preventing silent hangs
- First-byte timing logged for every request for observability
- Health endpoint now reports firstByteTimeout in config
- Default timeout: 300s → 120s (CLAUDE_TIMEOUT)
- New: first-byte timeout at 30s (CLAUDE_FIRST_BYTE_TIMEOUT) — aborts early
if Claude CLI produces no stdout, triggering faster fallback
- Pool disabled by default (POOL_SIZE=0) — on-demand spawning is now the
default; set CLAUDE_POOL_SIZE>0 to re-enable
- Health endpoint now reports timeout and firstByteTimeout values
- Startup log shows pool mode (disabled/on-demand vs active)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Major architectural upgrade:
- Replace pool system with on-demand spawning (eliminates crash loops,
DEGRADED states, and stdin timeout errors from v1.x)
- Add session management with --resume support (reduces token waste on
multi-turn conversations)
- Expand default allowed tools (Bash, Read, Write, Edit, Glob, Grep,
WebSearch, WebFetch, Agent) with configurable CLAUDE_ALLOWED_TOOLS
- Add system prompt pass-through (CLAUDE_SYSTEM_PROMPT)
- Add MCP config support (CLAUDE_MCP_CONFIG)
- Add concurrency control (CLAUDE_MAX_CONCURRENT, default 5)
- Add periodic auth health monitoring
- Add session API endpoints (GET/DELETE /sessions)
- Improve /health with full diagnostics (stats, sessions, errors, config)
- Fix timeout race condition (graceful SIGTERM → SIGKILL)
- Fix ERR_HTTP_HEADERS_SENT by checking headersSent in all response helpers
- Document coexistence with Claude Code interactive mode (Telegram, IDE)
- No conflict with CC: different ports, protocols, and process models
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The proxy previously defaulted to bare "claude" command which fails in
macOS LaunchAgent where PATH is minimal. Now resolves the binary at
startup via: CLAUDE_BIN env → well-known paths → which fallback.
Fails fast with clear error if binary cannot be found.
Also enhances /health to report claudeBinary and claudeBinaryOk status.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add optional PROXY_API_KEY env var for Bearer token auth
- Return 401 for missing/invalid token on all endpoints except /health
- Skip auth when PROXY_API_KEY is not set (backwards compatible)
- Log auth status on startup
- Rework replenishPool to accept isCrash flag: initial fills spawn
immediately with no delay; only crash-triggered respawns apply backoff
- Exponential backoff on crash: 2s, 4s, 8s, 16s, 32s, capped at 60s
- After 5 consecutive fast crashes (< 10s lived) within a 60s rolling
window, mark model as "degraded" and stop all respawning to prevent
CPU spin loops
- Degraded state resets automatically if a subsequent spawn lives > 10s
- stderr from crashed pool workers is captured and logged on exit
- Bump version to 1.6.0
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- setup.mjs: install launchd plist (macOS) or systemd user service (Linux) after proxy starts; logs to ~/.openclaw/logs/proxy.log
- Add uninstall.mjs to stop and remove the auto-start entry
- README: Quick Start (Node.js) first, Security section, Docker moved to Server/Advanced
- Bump version to 1.5.0
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The v1.3.0 process pool refactor changed --allowedTools to --tools ""
which disabled all CLI tools. This caused agents to output raw <tool_use>
XML as text instead of executing tools. Restored --allowedTools with
Bash, Read, Write, Edit, Glob, Grep in both spawnWarm() and callClaude()
cold-start paths. Bumped version to 1.3.1.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Changes since 1.0.0:
- SSE streaming support for OpenClaw compatibility
- --allowedTools flag for non-interactive tool approval
- Recovery and troubleshooting docs in README
- setup.mjs auto-configuration script
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
claude -p in non-interactive mode cannot show approval prompts,
so tools like gh/git were blocked. Add --allowedTools to enable
tool execution without manual approval.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Routes OpenClaw requests through `claude -p` CLI, letting you use
Claude Pro/Max subscriptions as a model provider without API keys.
- SSE streaming + non-streaming responses
- Auto-setup script for OpenClaw configuration
- Supports Opus 4.6, Sonnet 4.6, Haiku 4
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>