agent-proxy — a zero-dep proxy that shows the bloat in Claude Code's requests (ranked tool table + full readable Markdown of every request) A developer built agent-proxy, a zero-dependency logging proxy for Claude Code that sits between the CLI and the Anthropic API. The proxy forwards requests untouched and writes readable Markdown documents with a ranked table of what consumes context, revealing bloat in Claude Code's requests. | / | | agent-proxy — see what Claude Code actually sends the model. | | | | A zero-dependency logging proxy for Claude Code. It sits between the CLI and | | the Anthropic API, forwards every request untouched auth header and all , | | streams the response straight back so the CLI is unaffected, and for each | | request writes a readable Markdown document — led by a ranked table of what | | is eating your context. | | | | Run: node proxy.mjs | | Point Claude Code at it: | | ANTHROPIC BASE URL=http://localhost:8787 claude | | | | Zero runtime dependencies — Node built-ins only. Requires Node 18+. | | / | | | | import http from "node:http"; | | import https from "node:https"; | | import fs from "node:fs"; | | import path from "node:path"; | | import { fileURLToPath } from "node:url"; | | | | const PORT = Number process.env.PORT ?? 8787 ; | | const UPSTREAM = "api.anthropic.com"; | | | | const HERE = path.dirname fileURLToPath import.meta.url ; | | const LOG DIR = path.join HERE, "logs" ; | | | | / Rough token estimate for display. Real input tokens come from the response | | usage; this is only for ranking the request before the reply arrives. / | | const estTokens = bytes = Math.round bytes / 4 ; | | | | / count tokens calls send content but get back only a number, never a reply. | | A single turn fires many as housekeeping — pure noise here, so skip them. / | | const isTokenCount = reqPath = reqPath.includes "count tokens" ; | | | | const REDACT = new Set "authorization", "x-api-key", "api-key" ; | | | | / Strip hop-by-hop and encoding headers so the captured response is readable, | | recompute content-length, and pass auth through untouched so the real request | | still authenticates. / | | function forwardHeaders headers, body { | | const out = { ...headers }; | | delete out "host" ; | | delete out "connection" ; | | delete out "accept-encoding" ; // force identity so we can read the stream | | delete out "transfer-encoding" ; | | delete out "content-length" ; | | if body.length 0 out "content-length" = String body.length ; | | return out; | | } | | | | function baseName { | | const stamp = new Date .toISOString .replace /:/g, "-" .replace ".", "-" .replace "Z", "" ; | | return ${stamp} anthropic ; | | } | | | | // --------------------------------------------------------------------------- | | // The audit: rank what's in the request | | // --------------------------------------------------------------------------- | | | | / Measure every removable region of the request and rank the tools by size. | | This is the whole point of the proxy — the numbers you cut against. / | | function auditRequest reqJson, realInputTokens { | | const tools = Array.isArray reqJson?.tools ? reqJson.tools : ; | | const toolRows = tools | | .map t = { | | const bytes = Buffer.byteLength JSON.stringify t ; | | return { name: t?.name ?? " unnamed ", bytes, tokens: estTokens bytes }; | | } | | .sort a, b = b.bytes - a.bytes ; | | | | const toolsBytes = toolRows.reduce n, r = n + r.bytes, 0 ; | | const systemBytes = reqJson?.system ? Buffer.byteLength JSON.stringify reqJson.system : 0; | | const totalBytes = Buffer.byteLength JSON.stringify reqJson ?? {} ; | | | | return { | | toolRows, | | toolCount: toolRows.length, | | toolsBytes, | | systemBytes, | | totalBytes, | | realInputTokens, | | }; | | } | | | | / The ranked table, as Markdown. The hero of the whole document. / | | function renderAudit a { | | const pct = b = a.totalBytes ? b / a.totalBytes 100 .toFixed 1 : "0.0" ; | | const rows = a.toolRows | | .map r = | ${r.name} | ${r.bytes.toLocaleString } | ~${r.tokens.toLocaleString } | ${pct r.bytes }% | | | .join "\n" ; | | | | return | | "