pihme / claude-budget-mcp

claude-budget-mcp

A small local MCP server that tells a Claude Code agent how much of its 5-hour and weekly usage limits is left, the same figures as /usage. Read-only, unofficial endpoint.

Get startedGitHubReadme

CI · releases tagged claude-budget-mcp/vX.Y.Z

#What it is

claude-budget-mcp is a small, local MCP server that lets a Claude Code agent ask: how much of my 5-hour and weekly usage limits is left, and when do they reset? It answers with the same figures the interactive /usage command shows for a Claude subscription (Pro, Max, Team, Enterprise), as JSON.

An agent has no first-class way to get these numbers today: /usage is interactive, and the status line’s rate limits only reach the status line script. The server reads your existing Claude Code login, makes one HTTPS request per tool call and returns the figures. It never refreshes or writes the login.

Unofficial endpoint. The server calls the private route Claude Code itself uses for /usage. It is not a public Anthropic API and can change at any time; the server then fails loudly instead of guessing. Use it as a personal, local helper with your own account. Not affiliated with or endorsed by Anthropic.

#Current status

Last updated 2 October 2026 · main@e5ff717

All 29 tests pass on the main branch in continuous integration, on Node.js 22 and 24. The budget tool returns the used and remaining share of the 5-hour session window and of the weekly window, their reset times, every per-model window the service reports, and the plan type. One test starts the server the way Claude Code does and calls the tool end to end. A missing or expired login, rate limits, timeouts and changed responses come back as clear errors, and the tests check that the login file is never changed and the token never appears in a result. The latest release is claude-budget-mcp/v0.1.0. Releases are cut automatically after the tests pass.

The server has not yet been tried against the live service with a real login; the automated tests use made-up sample responses. It depends on an endpoint that Anthropic does not document, so it can break whenever Anthropic changes it, and it then reports a warning or an error instead of guessing. It never renews the login: when the token runs out, the user simply uses Claude Code, which renews its own login, or signs in again. It reads the login file Claude Code keeps on Linux, not the macOS Keychain. There is no package on the npm registry. There are no open issues.

#Key concepts

One tool

get_budget takes no input and returns the 5-hour session window, the weekly window and every per-model window the endpoint reports.

Read-only login

Reads $CLAUDE_CONFIG_DIR/.credentials.json or ~/.claude/.credentials.json and uses claudeAiOauth.accessToken. Never refreshes, never writes, never calls an auth endpoint.

Why never refresh

Claude Code rotates its refresh token on every refresh. A second refresh from outside could sign out its sessions (claude-code#78020), so an expired token is reported as an error instead.

One request per call

Each call re-reads the login file and sends one GET with a 15 s timeout. No retries, no caching, no polling.

Never invents numbers

Missing fields are null and explained in warning. Nothing usable means an error.

Honest client

The token, the Authorization header and the raw response are never logged or returned. The server names itself in its User-Agent and does not pretend to be Claude Code.

#Getting started

Needs Linux, Node.js 22+ and Claude Code logged in with a Claude subscription (/login). On macOS Claude Code keeps its login in the Keychain, which this version does not read.

git clone https://github.com/pihme/claude-budget-mcp.git
cd claude-budget-mcp
npm install        # also builds dist/ via the prepare script
npm test           # offline: mocked endpoint, synthetic credentials files

Or take the prebuilt package from the latest release (built dist/, no build step): npm install -g ./claude-budget-mcp-X.Y.Z.tgz puts claude-budget-mcp on your PATH. Nothing is published to npm.

Wire it into Claude Code (everything after -- is the server command):

claude mcp add --scope user claude-budget -- node /path/to/claude-budget-mcp/dist/index.js

Check it with claude mcp list or /mcp. The tool appears as mcp__claude-budget__get_budget. A good agent instruction, for example in CLAUDE.md: “Before long or expensive work, call mcp__claude-budget__get_budget once; if the session or weekly remaining percent is low, tell me and ask before continuing.”

npm run smoke is an optional manual check: it starts the server and calls get_budget once with your real login. More in the readme and the official Claude Code MCP docs.

#Tools & output

get_budget always returns every field; anything the endpoint did not send is null.

FieldMeaning
session_used_percent, session_remaining_percentThe rolling 5-hour session window (five_hour); remaining is clamped to 0–100
session_resets_atWhen the 5-hour window resets
weekly_used_percent, weekly_remaining_percent, weekly_resets_atThe weekly window across all models (seven_day)
windowsEvery window found as { window, used_percent, remaining_percent, resets_at }, including per-model buckets such as seven_day_opus and weekly_scoped:<model> rows
subscription_typeYour plan as Claude Code stored it (for example max), or null
source, fetched_atWhere and when the figures were fetched
warningPlain note when data is partial or the shape looks different; null when complete

Errors

Returned as MCP tool errors (isError: true) with a code and a readable message; the login errors tell you to use Claude Code once or run /login.

CodeWhen
NOT_LOGGED_IN.credentials.json missing or unreadable
AUTH_SHAPE_UNEXPECTEDNo claudeAiOauth.accessToken: an API key, Bedrock or Vertex login has no usage windows
SESSION_EXPIREDexpiresAt is in the past; no request is made
UNAUTHORIZEDHTTP 401 / 403
RATE_LIMITEDHTTP 429; retry later, not in a loop
REQUEST_FAILEDOther HTTP status, network error or 15 s timeout
SHAPE_CHANGED200, but not JSON, or no usage window could be read
INTERNALAnything unexpected; details are never echoed

#Architecture & layout

Your machine (Linux)Claude Codeagent · MCP clientclaude-budget-mcpstdio MCP server (node).credentials.json$CLAUDE_CONFIG_DIR or ~/.claudeapi.anthropic.com/api/oauth/usage · unofficialtool callJSON resultreads accessToken + expiresAt/login writesone GET per call

Claude Code starts the server as a child process and talks MCP over stdin/stdout. Per tool call the server reads .credentials.json without changing it and sends one GET /api/oauth/usage with the access token as Bearer token. Diagnostics go to stderr only.

PathContents
src/index.tsEntry point: stdio transport
src/server.tsTool registration and error mapping
src/budget.tsOne call: read the login, one request, map the result
src/auth.tsRead-only .credentials.json access and expiry check
src/usage.tsHTTP client and field mapping for the usage endpoint
src/errors.tsError codes
test/node:test suites with a mocked endpoint and synthetic fixtures, plus a stdio end-to-end test
scripts/smoke.mjsManual check against your real login
SPEC.mdDesign, research and decisions