claude-relay

skill
Guvenlik Denetimi
Uyari
Health Uyari
  • License — License: MIT
  • Description — Repository has a description
  • Active repo — Last push 0 days ago
  • Low visibility — Only 8 GitHub stars
Code Uyari
  • process.env — Environment variable access in clients/ts/claudeRelay.ts
  • network request — Outbound network request in clients/ts/claudeRelay.ts
Permissions Gecti
  • Permissions — No dangerous permissions requested

Bu listing icin henuz AI raporu yok.

SUMMARY

Self-hosted, secured HTTP API around headless Claude Code — per-app keys, all tools locked off, zero deps. Use Claude from your own apps.

README.md

claude-relay

Turn the Claude Code you already run into a tiny, secured HTTP API for your own apps.

Self-hosted. One file of stdlib Python. Per-app keys, rate limits, and every tool locked off
so a prompt can never touch your machine.

CI
License: MIT
Python
Dependencies
PRs welcome


You run Claude Code on a machine where you're logged in. claude-relay wraps claude -p
behind a small HTTP endpoint so any of your apps, scripts, or cron jobs can call Claude over
the network — instead of wiring the Anthropic SDK into each one.

curl -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d '{"system":"You are terse.","prompt":"Name 3 primary colors as a JSON array."}' \
  https://your-relay.example/v1/complete
# {"ok":true,"model":"opus","duration_ms":1900,"text":"[\"red\",\"green\",\"blue\"]"}
  • 🔒 Can't be turned against your machine. Every call runs with all tools and MCP disabled
    no bash, no file access, no network. Pure text in → text out. (There's a test that proves it.)
  • 🔑 Per-app keys. Each app gets its own key (sha256-hashed at rest), revocable in one command,
    applied instantly. Plus rate limits and a concurrency cap so nothing runs away.
  • 🪶 Tiny + boring. One ~250-line Python file, zero dependencies, installs as a systemd --user
    service with no root. Easy to read, audit, and trust.

[!IMPORTANT]
Know your plan's terms. Claude consumer subscriptions and Claude Code are intended for
individual, interactive use. Pointing a production app — or other people's traffic — at a
personal subscription may violate Anthropic's terms and can get your account suspended. Use this
for your own projects, internal tools, and automation, and keep volume sane. For products that
serve customers or need guaranteed throughput, use the Anthropic API.
You are responsible for complying with the terms of whatever account you point it at.

Quickstart

On a Linux host where claude is installed and logged in:

git clone https://github.com/dimabru/claude-relay ~/claude-relay
cd ~/claude-relay
./install.sh                # starts the service (systemd --user, no root)
./bin/genkey my-app         # mint a key — copy the secret it prints

That's it — the relay is live on 127.0.0.1:8799. No systemd? Just ./run.sh to run it in the
foreground.

Expose it (permanent URL, no domain to buy)

The service binds to localhost; a tunnel is the only way in. Easiest free option — an
ngrok dev domain (one permanent *.ngrok-free.dev, no domain needed):

ngrok config add-authtoken <YOUR_TOKEN>        # free account
# claim your free domain at https://dashboard.ngrok.com/domains, then put it in config.env:
#   NGROK_DOMAIN=your-name.ngrok-free.dev
cp systemd/claude-relay-ngrok.service ~/.config/systemd/user/
systemctl --user daemon-reload && systemctl --user enable --now claude-relay-ngrok

Already on Tailscale? tailscale funnel 8799 gives a permanent https://<host>.<tailnet>.ts.net
with no extra account.

API

POST /v1/completeAuthorization: Bearer <key>

field required notes
prompt the user prompt
system system prompt
model opus (default), sonnet, or haiku
output_format text (default) → {text}; json{result, usage}

POST /v1/fetchAuthorization: Bearer <key> — proxy a page fetch through the relay host's
IP (for apps on datacenter IPs that shops/search engines bot-wall). SSRF-guarded (private/loopback
targets rejected on every redirect hop), size-capped, and rate-limited in its own bucket so page
fetches never spend the LLM budget.

field required notes
url http/https, must resolve to a public address
max_bytes HTML size cap in the response (default 500 KB, max 2 MB)
strip default true: drop scripts/styles/svg/comments, keep JSON-LD

{ok, status, final_url, truncated, html}.

Also GET /v1/models (auth) and GET /health (no auth). Errors: 401 unauthorized, 400 bad
request, 413 too large, 429 rate limited (+Retry-After), 502/504 upstream error/timeout.

Use it from an app

Drop-in TypeScript and Python
clients read CLAUDE_RELAY_URL + CLAUDE_RELAY_KEY from the environment. Server-side only
never ship the key to a browser.

import { complete } from "./claudeRelay";
const colors = await complete({ system: "Output only JSON.", prompt: "3 primary colors", outputFormat: "json" });

Security model

Three independent layers — see SECURITY.md for the full threat model.

Goal How
A prompt can't touch the host every claude -p runs --disallowed-tools <all> + --strict-mcp-config --mcp-config '{}', default permission mode, throwaway cwd. Never --dangerously-skip-permissions.
Your account can't be drained global concurrency cap + per-key requests/minute & per-day + a global daily cap → 429 Retry-After.
Only your apps get in per-client bearer keys, sha256-hashed in keys.json, labeled, revocable, hot-reloaded. Binds 127.0.0.1 only. Audit log records label/model/status/duration — never prompt content.

No secrets in the repo: config.env, keys.json, and your tunnel token are gitignored; your Claude
login stays in ~/.claude, never here.

Manage keys

./bin/genkey <label> [daily_limit]   # mint (prints the secret once)
./bin/revoke <label>                 # revoke — effective immediately (hot-reloaded)

Configure (config.env)

PORT, DEFAULT_MODEL, ALLOWED_MODELS, MAX_INPUT_BYTES, REQ_TIMEOUT, GLOBAL_CONCURRENCY,
PER_KEY_RPM, PER_KEY_DAILY, GLOBAL_DAILY, NGROK_DOMAIN.

Who it's for

✅ Your side projects, internal tools, scripts, cron jobs, and homelab automation — one place to
call Claude from anything you own.

🚫 Not a way to resell Claude, run a public service on a personal plan, or dodge the API for a
product with real users. That risks your account and isn't what subscriptions are for.

FAQ

Does this need an Anthropic API key? No — it shells out to your logged-in Claude Code. (See the
terms note above.)

Can a caller make Claude run shell commands on my box? No. Tools are denied at the CLI level and
proven blocked by a test; the service also binds to localhost only.

Why not just use the API? If you can, use the API — it's the supported path for apps. This exists
for personal use of a subscription you already pay for.

Windows / macOS? The service is pure Python and runs anywhere via ./run.sh; the install.sh
helper targets Linux + systemd --user.

Contributing

Issues and PRs welcome — see CONTRIBUTING.md. Be kind: Code of Conduct.

License

MIT. Not affiliated with Anthropic. "Claude" is a trademark of Anthropic.

Yorumlar (0)

Sonuc bulunamadi