Rotor — the Meterhouse metering agent. Reads Claude Code usage on this machine and reports it to your Meterhouse dashboard.
Project description
Rotor — Install & Scan Guide
Rotor is the Meterhouse metering agent: the part that sits on each machine and turns as work happens. It scans Claude Code's local transcript files, stores usage in a local SQLite database, and (optionally) syncs it to the central server. Scanning works fully offline — no server required.
Installed as meterhouse-rotor; the command it provides is meterhouse.
Tracked activity ≠ official quota. All numbers are token counts parsed from local transcripts — an estimate, not your Claude Max/Pro billing or quota.
1. Prerequisites
- Python 3.10+ (check with
python --version) - Claude Code installed and used at least once on this machine, so transcripts
exist under
~/.claude/projects/(Windows:%USERPROFILE%\.claude\projects\).
The agent uses only the Python standard library — there is nothing to
pip install for scanning.
For central mode (sending usage to the dashboard) you install the
meterhousecommand from the repo, which needs git onPATH— see §7.
2. Install
Clone the repository and move into the agent folder:
git clone <your-repo-url> meterhouse
cd meterhouse\agent
You can run it three ways:
A. Install from PyPI (public release) — once published, users can install:
pip install meterhouse-rotor
B. No install (simplest) — run it as a module from the agent/ folder:
python -m meterhouse --help
C. Install the meterhouse command locally (so you can run it from anywhere):
pip install -e .
meterhouse --help
Both install options are equivalent for command usage; the rest of this guide uses python -m meterhouse.
The package is now public-ready as
meterhouse-rotor. If the package has already been published on PyPI, use thepip install meterhouse-rotorcommand above.
3. Use the agent as a Python SDK
The package now exposes a simple SDK interface via meterhouse.Agent.
Install the package
pip install -e .
Example usage
from meterhouse import Agent
agent = Agent(display_name="PC-01")
agent.register(
server_url="http://127.0.0.1:8000",
api_key="cfk_...",
display_name="PC-01",
)
print(agent.scan())
print(agent.sync())
print(agent.health())
The SDK also supports running the daemon programmatically:
agent = Agent(display_name="PC-01")
agent.daemon()
4. Run a scan
Give this machine a name (once), then scan:
python -m meterhouse identity --display-name PC-01
python -m meterhouse scan
Example output:
[NEW] C:\Users\you\.claude\projects\my-proj\<uuid>.jsonl (+266 events)
...
scan complete: new=18 updated=0 skipped=0 events+=1787
The scan is incremental and idempotent:
- Unchanged files are skipped; changed files are read only from where they left off.
- Running it again processes nothing new (
events+=0) — it never double-counts.
Run scan whenever you want fresh data (or schedule it — see §6).
4. View your usage
python -m meterhouse today # today's tokens by model
python -m meterhouse week # last 7 days
python -m meterhouse stats # all-time totals, by model, top projects
stats example:
Meterhouse - all-time tracked usage
Sessions: 13
Input tokens: 6.2M Output tokens: 1.1M Cache read: 280M ...
By model: claude-opus-4-8 ... claude-sonnet-5 ...
Top projects: Github/hotel-demo ...
(estimate only - not official Max/Pro quota)
5. Where your data lives
| What | Default location | Override with |
|---|---|---|
| Usage database | ~/.claude/meterhouse/usage.db |
METERHOUSE_DB |
| Machine identity/config | ~/.claude/meterhouse/agent.json |
METERHOUSE_CONFIG |
| Transcripts it reads (read-only) | ~/.claude/projects/**/*.jsonl |
auto-discovered |
Example with a custom DB path (PowerShell):
$env:METERHOUSE_DB = "D:\data\usage.db"
python -m meterhouse scan
The agent never modifies Claude Code's files and never stores prompts, responses, or source code — only token counts and metadata.
6. Automatic scanning (Windows Task Scheduler)
Run a scan every 15 minutes without thinking about it (one line):
schtasks /Create /SC MINUTE /MO 15 /TN "Meterhouse Scan" /TR "python -m meterhouse scan --quiet" /ST 00:00
If you installed via the "Connect PC" flow (§7) or deploy/install.ps1, the
task is instead named "Meterhouse Scan+Sync" and also pushes data to the
central server every 15 minutes.
Stop the agent from scanning
Remove whichever scheduled task applies to how you installed:
schtasks /Delete /TN "Meterhouse Scan" /F # local scan-only task
schtasks /Delete /TN "Meterhouse Scan+Sync" /F # Connect PC / install.ps1 task
To pause it instead of deleting it (keeps run history, easy to re-enable):
schtasks /Change /TN "Meterhouse Scan+Sync" /DISABLE
schtasks /Change /TN "Meterhouse Scan+Sync" /ENABLE # resume later
schtasks /TRdoes not go throughcmd.exe, so a rawscan && synccommand line will not chain correctly — it's run via a smallmeterhouse-scan-sync.cmdwrapper batch file instead. If you set the task up by hand, point/TRat a.cmdwrapper rather than an inline&&.
7. Send data to the central server (optional)
Local scanning is enough for one machine. To feed a central dashboard:
- Sign in to the web app and open Connect PC (or ask your admin for an API key).
- The web app generates a one-line setup command for the machine you want to track. This is the command you run in PowerShell on that PC.
- The command installs the agent, registers the machine with the server, scans local Claude Code transcripts, and syncs the results back to the dashboard.
If you only have the website link, that is enough. The site does not scan your PC from the browser; it only generates the install/connect command and gives you the server URL and API key to use.
pip install meterhouse-rotor
meterhouse register --server https://YOUR-API-URL --api-key cfk_... --display-name PC-01
meterhouse scan
meterhouse sync
Or use the Windows installer from the repo (deploy/install.ps1), which does
all four steps above and sets up the recurring scan+sync task automatically.
--servermust be the API server (e.g.http://localhost:8000in dev), not the dashboard's frontend URL (http://localhost:5173/...). Pointing it at the frontend URL will fail to register.
The agent connects by calling the server at the given API URL and authenticating with the supplied API key. After registration, it reads local transcript files, aggregates token events, and sends only usage metadata to the dashboard.
An administrator can also create an API key under Admin → Agent API keys, then share the key and API URL with each user.
sync only sends events the server hasn't seen; if the server is down it simply
retries next time (nothing is lost, nothing is double-counted). The dashboard
shows a system as "Never synced" until the first successful sync call —
registering alone, or running scan without sync, is not enough.
8. Troubleshooting
| Symptom | Fix |
|---|---|
scan complete: new=0 ... events+=0 on first run |
No transcripts found. Confirm %USERPROFILE%\.claude\projects\ exists and you've used Claude Code. |
python not found |
Install Python 3.10+ and ensure it's on PATH (py -3 also works on Windows). |
| Want a clean re-scan | Delete the usage DB (%USERPROFILE%\.claude\meterhouse\usage.db) and run scan again. |
sync says "Central mode not configured" |
Run register first with --server and --api-key. |
sync fails / offline |
Expected when the server is unreachable; it retries on the next run. |
Command reference
python -m meterhouse scan [--display-name NAME] [--quiet]
python -m meterhouse today | week | stats
python -m meterhouse identity [--display-name NAME] [--set-display-name NAME]
python -m meterhouse register --server URL --api-key KEY [--display-name NAME]
python -m meterhouse sync [--quiet]
python -m meterhouse heartbeat
python -m meterhouse account [show | enable | disable]
python -m meterhouse --version
Claude account reporting (optional, off by default)
account controls whether this machine also reports which Claude
subscription it is signed into, so an admin can see who is on which plan and
how much of its rate limit is used.
python -m meterhouse account show # print the exact payload - sends nothing
python -m meterhouse account enable
python -m meterhouse account disable
Enabled, the agent reads a fixed allowlist of fields from ~/.claude.json:
account UUID, email, display name, organisation, plan tier, and the cached
rate-limit percentages. OAuth tokens and credentials are never read, and
.credentials.json is never opened. See meterhouse/account.py for the
allowlist and tests/test_account.py for the tests that enforce it.
Equivalent env var: METERHOUSE_ACCOUNT_REPORTING=true.
Run the test suite with pip install pytest && python -m pytest.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file meterhouse_rotor-0.2.2.tar.gz.
File metadata
- Download URL: meterhouse_rotor-0.2.2.tar.gz
- Upload date:
- Size: 45.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b30f8ee9fe19fff2290083ce684901fb471458fd163215e78879ed002c324b11
|
|
| MD5 |
370ae3fedf9cae175d00a28d76dbb050
|
|
| BLAKE2b-256 |
038e9f165268fc86a82682806a721ecfb778bb95f066c11bc2c42b12a5db0fdd
|
Provenance
The following attestation bundles were made for meterhouse_rotor-0.2.2.tar.gz:
Publisher:
publish-agent.yml on Aniruth-Sakthivel/claude-code-uusage
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
meterhouse_rotor-0.2.2.tar.gz -
Subject digest:
b30f8ee9fe19fff2290083ce684901fb471458fd163215e78879ed002c324b11 - Sigstore transparency entry: 2319898638
- Sigstore integration time:
-
Permalink:
Aniruth-Sakthivel/claude-code-uusage@75c3432794e73869b1408a005bec54664e4121a3 -
Branch / Tag:
refs/tags/agent-v0.2.2 - Owner: https://github.com/Aniruth-Sakthivel
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-agent.yml@75c3432794e73869b1408a005bec54664e4121a3 -
Trigger Event:
push
-
Statement type:
File details
Details for the file meterhouse_rotor-0.2.2-py3-none-any.whl.
File metadata
- Download URL: meterhouse_rotor-0.2.2-py3-none-any.whl
- Upload date:
- Size: 39.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0a3ef674ddc8406d01ebf24e453abd4c4d6222f6a64fee6972d95efa955a3e8b
|
|
| MD5 |
0170a66737e1c8edcb05c6af13488b6b
|
|
| BLAKE2b-256 |
1a2aa05e5cca59644f3fe7509002904fe6790657b98d11e6a5d9c8eb5854a06b
|
Provenance
The following attestation bundles were made for meterhouse_rotor-0.2.2-py3-none-any.whl:
Publisher:
publish-agent.yml on Aniruth-Sakthivel/claude-code-uusage
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
meterhouse_rotor-0.2.2-py3-none-any.whl -
Subject digest:
0a3ef674ddc8406d01ebf24e453abd4c4d6222f6a64fee6972d95efa955a3e8b - Sigstore transparency entry: 2319899100
- Sigstore integration time:
-
Permalink:
Aniruth-Sakthivel/claude-code-uusage@75c3432794e73869b1408a005bec54664e4121a3 -
Branch / Tag:
refs/tags/agent-v0.2.2 - Owner: https://github.com/Aniruth-Sakthivel
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-agent.yml@75c3432794e73869b1408a005bec54664e4121a3 -
Trigger Event:
push
-
Statement type: