Compares AI coding tool spend before and after a migration via MCP tools.
io.github.RudrenduPaul/teamspend (MCP Server)
This MCP server compares AI coding tool spend before and after a migration. It is distributed as an npm and PyPI package (teamspend-cli), and focuses on tracking costs across developer tooling. The repository is tagged for Node.js/TypeScript and includes references to common AI coding tools and migrations.
🛠️ Key Features
Compares AI coding tool spend before vs. after a migration
Cost tracking for AI coding tool usage
Implemented as teamspend-cli, published on npm and PyPI
🚀 Use Cases
Validate cost changes resulting from migrating AI coding tools
Track spend trends when adopting tools such as Claude Code or GitHub Copilot
Support FinOps-oriented reporting for developer tool usage
⚡ Developer Benefits
CLI-focused package for spend tracking (teamspend-cli)
Your AI coding tools will never tell you if switching between them actually saved money. teamspend does, in one command.
Terminal recording: installing teamspend-cli from a packed tarball, then running a claude-code-personal before/after comparison that prints total spend for each period and a DELTA line
The recording above uses claude-code-personal (credential-free, reads local session logs) so the install-to-first-run flow plays end to end with no admin API keys required; the live output shape is identical whichever adapter you point it at.
Six tools now, not two: Cursor, Claude Code, GitHub Copilot, OpenCode, and Codex CLI, plus a credential-free personal mode for anyone without admin access. More teams are running more than one AI coding tool at once, or moving between them, than ever before. Every one of those tools has a dashboard that's perfectly accurate about itself and structurally incapable of showing you anything else. teamspend is the missing piece: one real number, pulled straight from both tools' own APIs, showing exactly what changed.
Example output (shape shown below; your real numbers come from your own org's API data):
code
teamspend snapshot -- migration cost comparison
Tools: cursor -> claude-code
BEFORE (cursor)
Total spend: $2,140.00 (exact, usage-based)
Active users: 14
AFTER (claude-code)
Total spend: $1,860.00 (exact, usage-based)
Active users: 14
DELTA: -$280.00 (-13.1%)
Full report: ./teamspend-snapshot-2026-07-11T142842.json
That's the whole product. One command, one honest number, zero spreadsheets.
What it actually does
Pulls real numbers, not scrapes or estimates. Talks directly to Cursor's Admin API and Anthropic's Claude Enterprise Analytics API. What you see is what the vendor itself reports.
Compares across tools, which no single vendor dashboard will ever do. Cursor's dashboard shows Cursor. Claude Code's dashboard shows Claude Code. teamspend puts both numbers in the same sentence.
Fills historical gaps with CSV import. If your comparison window reaches back further than a tool's API history, hand it a CSV in the same shape and it folds those rows into the same report, no separate merge step.
Never fails silently. If one side of the comparison can't be fetched, you get a clear "data unavailable" and a reason, never a wrong number presented as a right one.
Retries the way a production client should. Rate limits, timeouts, and transient errors get exponential backoff automatically, capped and bounded, so a flaky API call doesn't mean a flaky result.
Flags suspicious zeros instead of trusting them. Flat-seat billing tiers on both Cursor and Claude Code can report an exact-looking $0 for a user with real token activity. teamspend detects that pattern and marks the number estimated rather than showing a misleading zero.
Ships with zero runtime dependencies. No supply chain to audit but our own code. Native fetch, native argument parsing, native file I/O.
Get started in under a minute
teamspend ships two independent, equally first-class packages -- pick
whichever fits your toolchain, or install both. They talk to the same six
data sources and compute the same before/after delta.
bash
# npm -- JavaScript/TypeScript CLI + library
npm install -g teamspend-cli
# PyPI -- Python CLI + library (genuine port, not a wrapper around the Node binary)
pip install teamspend-cli
Both packages are named teamspend-cli (the older plain teamspend name
was renamed to match this project's other packages, then fully unpublished
from both registries as of 2026-08-03 -- same maintainer, same repo, but
no longer installable under any version). Either way, the installed
command is teamspend.
Give it the two API keys for the tools you're comparing:
bash
export TEAMSPEND_CURSOR_TOKEN=<your Cursor Admin API key>
export TEAMSPEND_CLAUDE_CODE_TOKEN=<your Anthropic Admin/Analytics API key>
Both need org-admin-level access on their platform. If you can already see billing for your org, you have what you need.
Add --json to print the full JSON report to stdout instead of the
human-readable summary above -- useful for piping into another script or a
CI step. The JSON report file on disk is written either way; --json only
changes what prints to the terminal.
Comparing against GitHub Copilot instead? See
"GitHub Copilot support" below -- it needs two
more environment variables than Cursor/Claude Code do, for reasons that are
worth reading before you point it at a real org.
Both CLIs accept the same comparison flags (--tools, --before, --after,
--json, --before-csv, --after-csv, --breakdown, --help/-h,
--version/-V) and print the same output shape. See the
Commands section below for the full flag reference,
python/README.md for the Python package's library API,
and docs/getting-started.md for the full guide
covering both distributions.
Built to be trusted, not just used
A tool that touches your team's spend and email data should earn that trust in the open. Here's what's actually true about this codebase, checked on every commit, not asserted in a marketing paragraph:
Runtime dependencies
Zero
Package size
56.8 kB packed, 193.1 kB unpacked
Cold install to first response
Under 1 second, measured with a cleared npm/npx cache
Tests
102 passing (npm), 116 passing (PyPI), 97% line coverage on the TypeScript suite
Known vulnerabilities
Zero, per npm audit
File permissions
Report files are owner-only (0600) and auto-gitignored, since they hold per-user emails and spend
CSV import, for the history a live API can't reach
export TEAMSPEND_COPILOT_TOKEN=<a token with read:org on the org>
export TEAMSPEND_COPILOT_ORG=<your GitHub org login>
export TEAMSPEND_COPILOT_SEAT_PRICE_USD=19 # optional, see below
npx teamspend-cli --tools cursor,copilot --before 2026-04-01:2026-04-30 --after 2026-06-01:2026-06-30
Credential:TEAMSPEND_COPILOT_TOKEN needs the read:org scope (a
classic PAT) or the fine-grained "View Organization Copilot Metrics"
permission, and the org must be on Copilot Business or Enterprise.
TEAMSPEND_COPILOT_ORG is required too -- unlike Cursor's and Claude
Code's admin APIs, GitHub's Copilot metrics endpoint is scoped to a specific
org login in the URL path itself, not just the token.
How teamspend derives a dollar figure, honestly: GitHub's real, current
Copilot usage metrics API (GET /orgs/{org}/copilot/metrics/reports/ users-1-day, confirmed against GitHub's own docs while building this --
the older /orgs/{org}/copilot/metrics endpoint some other tools still
reference was sunset by GitHub on 2026-04-02 and no longer works) has no
cost or spend field anywhere. Copilot Business/Enterprise is flat-seat
billing ($19 or $39 per seat per month, bundling a matching monthly AI-credit
allowance), and GitHub does not expose an org's actual contracted seat price
through any API -- the same structural gap Cursor's and Claude Code's
flat-seat billing tiers already have in this tool.
What the API does return per user is ai_credits_used. teamspend converts
that to USD at GitHub's own published, fixed rate of 1 AI credit = $0.01
USD -- not invented, and not a negotiated per-org price. If you set
TEAMSPEND_COPILOT_SEAT_PRICE_USD, that flat price is added once per active
user for the whole comparison window (never once per day) to also reflect
the license cost the credits-only figure excludes; if you don't set it, the
reported number is credits-usage cost only and explicitly does not include
the seat fee.
Because there is no vendor-reported cost field to begin with, every Copilot
result -- with or without a seat price -- is marked isEstimated: true.
This is a stronger caveat than Cursor's and Claude Code's suspicious-zero
flag, which only fires on a specific zero-cost pattern: Copilot has no
native dollar figure to trust in the first place, so teamspend never claims
one. See docs/concepts.md
for the full mechanics, including why one comparison window means one API
call per calendar day rather than one call for the whole range.
OpenCode: local-only, no API key needed
OpenCode (formerly sst/opencode)
has no admin, team, or billing API at all -- it's a local CLI with no
organization-level usage endpoint, confirmed against its own README. There
is nothing for TEAMSPEND_OPENCODE_TOKEN to authenticate, so it doesn't
exist; teamspend instead reads OpenCode's own local session logs directly
off disk (~/.local/share/opencode/storage/message/, or
$OPENCODE_DATA_DIR if set), the same file format OpenCode itself writes
and that ccusage's OpenCode guide
and tokscale both already read.
Terminal recording: teamspend run with the OpenCode local-log adapter and --breakdown session, printing estimated total spend and a per-session cost table for both periods, then the overall DELTA line
Two honest caveats worth knowing before you trust this number:
It's this machine's usage, not your team's. OpenCode's local message
files carry no user or email field anywhere -- it's a single-developer
tool with no team concept -- so teamspend attributes everything it finds
to one synthetic user, the OS account that ran the command. Comparing a
whole team's OpenCode spend means running teamspend on each person's
machine, or collecting numbers out of band and using CSV
import.
The dollar figure is always marked estimated. OpenCode itself stores
cost: 0 for most models in its local message files (it has no live
pricing table of its own), so teamspend sums whatever cost value OpenCode
did record and always shows it as (estimated), never (exact, usage-based), even on the rare message where that field is genuinely
populated. Token counts (input/output/cache read/write) are exact --
it's only the dollar figure that's approximate.
Codex CLI: local-only, no API key needed
Codex CLI (OpenAI's coding agent CLI)
has no admin, team, or billing API either -- it's a local CLI, confirmed
directly against its own Rust source (codex-rs/). There is nothing for
TEAMSPEND_CODEX_TOKEN to authenticate, so it doesn't exist; teamspend
instead reads Codex's own local rollout logs directly off disk
(~/.codex/sessions/YYYY/MM/DD/rollout-*.jsonl, or wherever CODEX_HOME
points), the same on-disk format Codex itself writes and that ccusage's
Codex guide and
mrexodia/agent-cost-dashboard
both already read.
Three honest caveats worth knowing before you trust this number:
It's this machine's usage, not your team's. Same as OpenCode's local
files, Codex's rollout logs carry no user or email field anywhere, so
teamspend attributes everything it finds to one synthetic user, the OS
account that ran the command. Comparing a whole team's Codex spend means
running teamspend on each person's machine, or collecting numbers out
of band and using CSV import.
The dollar figure is always marked estimated -- and it's always
exactly $0. Codex's local logs don't even have a cost: 0
placeholder the way OpenCode's do -- there is no cost field on a
token_count event at all, only token counts. teamspend bundles no
per-token pricing table of its own, so it reports $0 and marks the
result (estimated) rather than guessing a dollar figure from a table
that would drift from OpenAI's real, negotiated pricing. Token counts
(input/output/cache read) are exact; the dollar figure just isn't
reported by Codex at all.
Only the last ~7 days are readable. Codex itself
background-compresses any rollout file older than 7 days to .jsonl.zst
(zstd); teamspend reads plain .jsonl only, the same call already made
for OpenCode's newer SQLite store, to avoid adding a dependency for a
secondary on-disk format. A window reaching back further than that will
under-report or come back empty for Codex -- pair it with
CSV import for
anything older.
Personal usage mode, for when you don't have admin access
Everything above needs org-admin credentials (TEAMSPEND_CURSOR_TOKEN, TEAMSPEND_CLAUDE_CODE_TOKEN) because it's pulling a whole team's numbers from a vendor's admin API. If you just want your own personal Claude Code spend and don't have (or don't want to use) org-admin access, use claude-code-personal instead of claude-code as the tool name:
This mode reads Claude Code's own local JSONL session logs straight off disk (~/.claude/projects/**/*.jsonl by default, or wherever CLAUDE_CONFIG_DIR/XDG_CONFIG_HOME points). No API key, no network call, no admin access -- it needs nothing but the logs Claude Code already writes on your machine. It reports on the single local user running the command, not a team.
Two honest caveats: it only sees what's on the machine you run it on, and not every logged entry carries an exact costUSD from Claude Code -- when one doesn't, that entry's tokens still count but its dollar amount is flagged isEstimated, same as every other estimated number this tool ever shows you (see "Flags suspicious zeros instead of trusting them" above). It composes with the CSV-import fallback too: pair claude-code-personal on one side with a --before-csv/--after-csv on the other if you're comparing your own usage against a hand-supplied number for a tool teamspend doesn't fetch directly.
Session-level cost breakdown
A flat total answers "what did we spend," not "what's driving it." Add --breakdown session to break that total down by session/conversation -- the same log data claude-code-personal and opencode already read, just grouped by the sessionId/sessionID each log entry already carries, instead of summed into one number:
Terminal recording: teamspend run with --breakdown session, printing a per-session cost table (session ID, dollar cost, request count) for both the before and after period, then the overall DELTA line
This adds a per-session table (top 10 by cost) to the terminal summary, and the full session array to the JSON report -- both opt-in. Without the flag, output is byte-for-byte what it always was.
A session is a bounded unit of one interaction -- the most honest proxy teamspend can offer for "cost per task." That's a real, defensible number: it comes straight from the log's own session identifier, nothing invented. What it is not is a measure of task success, quality, or ROI. No vendor -- not Anthropic, not Cursor, not GitHub -- exposes whether a given session's output was actually good, so teamspend never claims to know that, and never will. If a session cost $9 and another cost $1, that tells you where the dollars went, not which one was worth it.
Two honest limits on top of that:
Only available for the local-log-based tools.claude-code-personal and opencode read session-scoped data straight off disk, so they can group by it. cursor, claude-code, and copilot pull from each vendor's admin API, and none of those three APIs return anything below a per-user aggregate -- there is no session field anywhere in their response shape to group by. Passing --breakdown session with those tools prints a clear message explaining that, not an empty table or a fabricated one.
A session's dollar figure inherits whatever estimation status its underlying entries have. If any log line in a session is missing an exact cost, that session (and the entries within it) is flagged isEstimated, the same rule the flat total already follows.
Commands
Both teamspend-cli binaries (npm's dist/cli.js, PyPI's teamspend.cli:main) accept the same flag set and validate arguments the same way. This table is re-derived from the actual installed binary's --help output, not from memory:
Flag
Argument
Required
What it does
--tools
<a>,<b>
Yes
Exactly two tools to compare, e.g. cursor,claude-code. One of: cursor, claude-code, copilot, opencode, claude-code-personal, codex.
--before
YYYY-MM-DD:YYYY-MM-DD
Yes
The "before" comparison window.
--after
YYYY-MM-DD:YYYY-MM-DD
Yes
The "after" comparison window.
--before-csv
<path>
No
CSV fallback for the "before" tool if the admin API can't cover that window.
--after-csv
<path>
No
CSV fallback for the "after" tool, same rule.
--breakdown
session
No
Adds a per-session cost table to the terminal output and the JSON report. Only works with claude-code-personal and opencode (the two local-log adapters); the other four tools print an explanation instead of a fabricated breakdown.
--json
none
No
Prints the full JSON report to stdout instead of the human-readable summary. The report file on disk is written either way.
-h, --help
none
No
Prints usage and exits 0.
-V, --version
none
No
Prints the installed version and exits 0.
Exit codes:0 on a successful comparison (or on --help/--version), 1 on an invalid argument (unknown tool, malformed date range, missing required flag) or a comparison where either side failed to resolve. There is no partial-success exit code: a comparison with one side unavailable still exits 1, matching the report's own DATA UNAVAILABLE marker for that side.
One real difference between the two binaries worth knowing: npm's --help prints the full flag table above; the currently published PyPI 0.2.7 build's --help prints a single condensed usage line with the same flags but no per-flag descriptions. Both accept and validate the same flags identically, only the --help text itself differs in verbosity.
Library API reference
Both packages also work as an importable library, not just a CLI -- package.json's main/types fields and python/pyproject.toml's package layout both point at real, exported code, re-derived here from the actual source rather than assumed:
npm (TypeScript), import { ... } from "teamspend-cli":
Aggregation helpers used internally and safe to reuse against any UserUsage[] array.
The opencode, codex, and claude-code-personal adapters are CLI-only as of this writing: they're wired into src/cli.ts but not re-exported from src/index.ts, so they're reachable through the teamspend command but not yet through import { ... } from "teamspend-cli". Everything else exported from src/schema.ts, src/errors.ts, and src/compare.ts (types, error classes, DateWindow, AdapterResult) is available the same way.
PyPI (Python), from teamspend import ...:
python
from teamspend import fetch_cursor_spend, fetch_claude_code_spend, build_comparison
from teamspend.types import DateWindow
before = fetch_cursor_spend(DateWindow("2026-04-01", "2026-04-30"), cursor_api_key)
after = fetch_claude_code_spend(DateWindow("2026-06-01", "2026-06-30"), claude_api_key)
The Python package exports the same shape: fetch_cursor_spend, fetch_claude_code_spend, fetch_copilot_spend, import_from_csv, build_comparison, render_terminal_summary, write_json_report, plus the AdapterResult/DateWindow/ToolId/UserUsage types and the full error hierarchy (AuthenticationError, RetryExhaustedError, SchemaDriftError, DataUnavailableError, CSVSchemaError, EmptyCSVError, CSVRowError, InvalidCliArgError), listed in full in python/src/teamspend/__init__.py. Same as the npm package, the opencode/codex/claude-code-personal adapters are CLI-only, not yet re-exported from the package root.
No generated API doc site exists yet for either package (no TypeDoc or Sphinx build in CI) -- the tables above are the reference until one does.
MCP Server
teamspend ships a Model Context Protocol server so an AI agent
(Claude, Cursor, or any MCP-compatible client) can run a spend comparison directly, without a human
invoking the CLI by hand.
Install the extra:
bash
pip install "teamspend-cli[mcp]"
Add it to your MCP client's config (for Claude Desktop, claude_desktop_config.json):
The server exposes one tool, run, that shells out to the published teamspend npm binary with the
given arguments plus --json, and returns the parsed JSON result:
The local-log adapters (claude-code-personal, opencode, codex) scan real session files on
disk, so a call that uses them can take up to 30 seconds to return, especially against a large
~/.claude/projects/ or ~/.local/share/opencode/storage/ history. Transport is stdio, so there is
nothing to host: the MCP client spawns the server as a local subprocess. Source:
python/src/teamspend/mcp_server.py.
Roadmap
This started narrow on purpose: prove the idea on the two tools one real team was actually migrating between, get it right, then grow it. Next up, roughly in order of how often people ask:
GitHub Copilot adapter
OpenCode adapter
Codex CLI adapter
Non-USD billing support
Want one of these sooner, or a tool that isn't on the list? Open an issue and say so. That's genuinely how the order gets decided.
Good to know before you run it
This is a snapshot tool, not a running dashboard. It answers one question well and stops.
The output includes real emails and dollar amounts, printed to your terminal and saved to a report file. If you wire this into a scheduled CI job on a public repo, that data lands in your build logs, so check your CI provider's log visibility first.
Test fixtures are built from each vendor's published API docs, not a live account. If your first real run throws a parsing error, that's a genuine signal a vendor's API shape drifted, not a bug we're hiding from you. Open an issue, it helps everyone who runs into it next.
Flat-seat and per-seat billing tiers (Cursor plans without usage overage, Claude.ai Team/Enterprise seats) don't expose true per-user cost through the vendor's own Admin API. When teamspend sees a user with real token or request activity but a reported cost of exactly $0, it marks that user's number, and the whole report, as estimated rather than showing a misleading exact-looking $0.
The PyPI package's --version currently reports the version string from the 0.2.2 release rather than reading it from the installed distribution's own metadata; the fix already lives on main and ships in the next PyPI release. pip show teamspend-cli always reports the real installed version in the meantime.
What is teamspend, and why does it exist
teamspend is a command-line tool that answers one question: when a team moves from one AI coding tool to another, or runs two at once, what did that actually cost, in real dollars, pulled straight from each vendor's own admin API?
It exists because no vendor's dashboard can answer that question, structurally. Cursor's Admin API reports Cursor spend. Anthropic's Claude Enterprise Analytics API reports Claude Code spend. Neither has a reason to show a competitor's number next to its own, so a team mid-migration is left opening two dashboards and doing the subtraction by hand. teamspend does the same thing a diff does for two files: it pulls both sides through the same normalized schema and prints one honest delta.
It is deliberately narrow. teamspend does not run continuously, does not host a dashboard, and does not track more than a before/after window for two tools at a time. It is a single command that answers a single question and exits.
Why this matters right now. AI coding agent spend has stopped being a rounding error. Uber's CTO disclosed to The Information that the company's engineering org burned through its entire 2026 AI tooling budget in about four months, as Claude Code adoption climbed from 32% to 84% across roughly 5,000 engineers (Forbes, Fortune) -- Uber's COO put it plainly: "it's very hard to draw a line between one of those stats and producing 25% more useful consumer features." Microsoft's Experiences and Devices division canceled internal Claude Code licenses and moved engineers to GitHub Copilot CLI after costs ran past its annual AI budget (The Verge, reported onward by Windows Central). A FinOps survey of 127 enterprise agentic AI deployments found 73% went over budget, some by up to 2.4x (TechTimes, beri.net). Every vendor answered with its own budget controls this year: Claude Enterprise shipped spend-threshold alerts, Cursor added team-level dollar caps, GitHub Copilot added org spending limits. None of them will ever show you a number from a competitor's tool next to their own. That gap is exactly what teamspend fills, and it's why the tool grew from two admin-API adapters to six real ways to pull a cost number.
How teamspend compares
This is a narrow tool built for one specific job. It is not trying to replace the two projects below, and if what you actually need is what they do well, use them instead.
$25M raised (seed + Series A), commercial platform
tokscale is a genuinely good project: 4,700+ stars, tracks personal token usage across 40+ coding-agent tools with a leaderboard and contribution graph. Checking its last 100 issues turns up zero requests for team budgets, manager dashboards, or spend rollups, because that's not the product it's building. If what you want is a personal usage tracker across every AI CLI you use, use tokscale. teamspend exists for a different question, the one a team's budget owner asks, not the one an individual contributor asks.
codeburn is the closest thing to real competition teamspend has: free, local-first, and it already breaks cost down by model, project, and task across more tools than teamspend covers. If what you want is a personal, single-machine cost breakdown across a wide tool list, codeburn does that better than teamspend does. What it doesn't do is pull from a vendor's admin API to answer the team-level, before-after migration question, which is the one thing teamspend was built for.
Vantage already ships live Cursor and Anthropic connectors as part of a broader cloud/SaaS/AI cost platform. If you're already consolidating your full cloud bill through Vantage, it's a solid choice and covers more ground than teamspend ever will. teamspend is for the narrower case: a lightweight, single-purpose tool for one migration decision, without adopting a full cost-management platform to get there.
Cursor's, Claude Code's, and Copilot's own admin consoles are each accurate for their own tool. Use them if you only run one. teamspend exists for the moment you're comparing two, because none of them will ever put a competitor's number in the same view as their own.
FAQ
What is teamspend, in one sentence?
A single command that pulls real, vendor-reported spend numbers for two AI coding tools and prints one before/after delta, so a team mid-migration doesn't have to open two dashboards and do the subtraction by hand. It deliberately does not run continuously or host a dashboard of its own -- see "What is teamspend, and why does it exist" above for the full case.
What do I need installed to run it, and on which platforms?
The npm package (teamspend-cli) needs Node.js 18.3.0 or newer, per the engines field in package.json; the PyPI package (also teamspend-cli) needs Python 3.9 or newer, per requires-python in python/pyproject.toml. Both list Operating System :: OS Independent and ship zero runtime dependencies, so there's no OS-specific setup beyond having that runtime available. The admin-API adapters (Cursor, Claude Code, Copilot) only need outbound network access to the vendor's API; the local-log adapters (OpenCode, Codex CLI, claude-code-personal) read files directly off the disk of the machine you run teamspend on and need no network access or credential at all.
How does teamspend compare to codeburn specifically, since they're the closest overlap?
codeburn already breaks cost down by model, project, and task across 31 tools, all on one machine, no admin API involved -- if that single-machine breakdown is what you need, codeburn does it better than teamspend does. teamspend answers a different question: it pulls from a vendor's admin API to compare what a whole team spent, before versus after a migration, which isn't something codeburn's local-tracking model does. Pick codeburn for a personal, cross-tool cost breakdown; pick teamspend for the team-level before/after number a budget owner has to report. The full comparison, including scale and star counts, is in "How teamspend compares" above.
Can I use teamspend commercially, or in a company codebase?
Yes. Both packages are Apache License 2.0 (see LICENSE and the license field in package.json/python/pyproject.toml), which permits commercial use, modification, and internal or redistributed use with attribution and without a copyleft requirement. There's no separate commercial tier or license to buy.
Does teamspend replace Cursor's or Claude Code's own admin console?
No. Each vendor's console is still the accurate source for that vendor's own numbers, and for anything beyond spend (seat management, usage policy, model access). teamspend exists for the one thing neither console does: putting both tools' numbers in the same comparison.
What happens if one tool's API call fails partway through?
The whole comparison is marked incomplete rather than silently reported as complete. buildComparison in src/compare.ts only computes a delta when both sides resolved; if either side failed, the report shows DATA UNAVAILABLE for that side and a null delta, never a number derived from a partial fetch.
Does teamspend store or send my team's spend data anywhere?
No. It's a local CLI: it calls each vendor's API directly from your machine, prints a summary to your terminal, and writes one JSON report file (0600 permissions) to your current directory. Nothing is sent to teamspend or any third party.
Can I use teamspend for tools other than Cursor and Claude Code?
Yes. GitHub Copilot is supported -- see "GitHub Copilot support" above, including an honest note on how its cost figure is derived since GitHub's own API has no dollar field to report. OpenCode and Codex CLI are supported too -- see OpenCode: local-only, no API key needed and Codex CLI: local-only, no API key needed above; both read their own local session logs directly, no API key required. A CSV-import fallback still covers any other tool in the meantime, using the same date,user_email,cost_usd,is_estimated schema documented above.
Why does a $0 spend number sometimes show up as "estimated" instead of exact?
Some billing tiers (flat-seat Cursor plans, Claude.ai Team/Enterprise seats) don't expose true per-user cost through the vendor's own Admin API and report an exact-looking $0 even for users with real activity. teamspend detects a $0 cost paired with non-zero token or request counts and flags it as estimated rather than presenting a misleading exact zero. See "Success stories" below for the two independent bug reports in other tools that led to this fix.
Does teamspend tell me if the money we spent was worth it?
No, and it never will pretend to. No vendor, not Anthropic, not Cursor, not GitHub, exposes whether a given session produced good code or wasted a budget. teamspend answers "what did this cost" with a real number pulled straight from the source; it does not and cannot answer "was it worth it." The session-level breakdown gets you as close as an honest tool can: cost per session, not cost per outcome.
Contributing
Found a rough edge, a vendor API that shifted shape, or a tool you wish this supported? Open an issue or a pull request. The codebase is small on purpose, so a fix or a new adapter is usually a smaller change than it looks. See CONTRIBUTING.md for the full guide covering both the npm (TypeScript) and PyPI (Python, python/) packages -- an adapter change should land in both.
code
# TypeScript (repo root)
npm install
npm run build
npm run lint
npm run typecheck
npm test
# Python (python/)
cd python
pip install -e ".[dev]"
pytest
If teamspend saved you from opening two dashboards and doing math by hand, a star helps other people with the same problem find it.
Success stories
The suspicious-zero fix above wasn't found in a vacuum. It came from watching another team hit the exact same wall in their own tool and treating their bug report as a spec.
liuzemei's PR to ccusage fixed the same root problem: on flat-seat billing, a vendor's own API can report cost_usd: 0 for a user who is clearly active, and a tool that trusts that number at face value ends up telling a team its top spender costs nothing. teamspend had the identical gap in its Cursor and Claude Code adapters. The two fixes take different routes though, ccusage recomputes a real dollar figure from its pricing table when it hits that zero, while teamspend takes the more modest step of just flagging the number as estimated instead of presenting a wrong zero as a real one.