teamspend
About
Compares AI coding tool spend before and after a migration via MCP tools.
Explore
Setting up with Highlight
This MCP is not yet compatible with Highlight’s one-click setup. However, you can still use it with Highlight by following these steps:
- Download and install Highlight from highlightai.com/download
- Navigate to the plugins tab and select "Add Custom Plugin"
-
Configure the plugin with the settings below
Plugin Name
teamspendCommand (node, npx, python, etc.)Please refer to the README for specific instructions on how to obtain API keys or other required environment variables.
- Enable "Start Automatically" if you want the plugin to start when Highlight launches
From the repository
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, useclaude-code-personalinstead ofclaude-codeas the tool name:
npx teamspend-cli --tools claude-code-personal,claude-code-personal --before 2026-04-01:2026-04-30 --after 2026-06-01:2026-06-30
This mode reads Claude Code's own local JSONL session logs straight off disk (~/.claude/projects//.jsonlby default, or whereverCLAUDE_CONFIG_DIR/XDG_CONFIG_HOMEpoints). 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 exactcostUSDfrom Claude Code -- when one doesn't, that entry's tokens still count but its dollar amount is flaggedisEstimated, 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: pairclaude-code-personalon one side with a--before-csv/--after-csvon the other if you're comparing your own usage against a hand-supplied number for a tool teamspend doesn't fetch directly.
A flat total answers "what did we spend," not "what's driving it." Add--breakdown sessionto break that total down by session/conversation -- the same log dataclaude-code-personalandopencodealready read, just grouped by thesessionId/sessionIDeach log entry already carries, instead of summed into one number:
npx teamspend-cli --tools claude-code-personal,claude-code-personal --before 2026-04-01:2026-04-30 --after 2026-06-01:2026-06-30 --breakdown session
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 isnotis 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.
- Only available for the local-log-based tools.claude-code-personalandopencoderead session-scoped data straight off disk, so they can group by it.cursor,claude-code, andcopilotpull 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 sessionwith 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 flaggedisEstimated, the same rule the flat total already follows.
Bothteamspend-clibinaries (npm'sdist/cli.js, PyPI'steamspend.cli:main) accept the same flag set and validate arguments the same way. This table is re-derived from the actual installed binary's--helpoutput, not from memory:
Exit codes:0on a successful comparison (or on--help/--version),1on 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 exits1, matching the report's ownDATA UNAVAILABLEmarker for that side.
One real difference between the two binaries worth knowing: npm's--helpprints the full flag table above; the currently published PyPI 0.2.7 build's--helpprints a single condensed usage line with the same flags but no per-flag descriptions. Both accept and validate the same flags identically, only the--helptext itself differs in verbosity.
Both packages also work as an importable library, not just a CLI --package.json'smain/typesfields andpython/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":
import { fetchCursorSpend, fetchClaudeCodeSpend, buildComparison } from "teamspend-cli"; const before = await fetchCursorSpend({ start: "2026-04-01", end: "2026-04-30" }, cursorApiKey); const after = await fetchClaudeCodeSpend({ start: "2026-06-01", end: "2026-06-30" }, claudeApiKey); const report = buildComparison( { label: "before", tool: "cursor", result: before, error: null }, { label: "after", tool: "claude-code", result: after, error: null }, );
Theopencode,codex, andclaude-code-personaladapters are CLI-only as of this writing: they're wired intosrc/cli.tsbut not re-exported fromsrc/index.ts, so they're reachable through theteamspendcommand but not yet throughimport { ... } from "teamspend-cli". Everything else exported fromsrc/schema.ts,src/errors.ts, andsrc/compare.ts(types, error classes,DateWindow,AdapterResult) is available the same way.
PyPI (Python),from teamspend import ...:*
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 theAdapterResult/DateWindow/ToolId/UserUsagetypes and the full error hierarchy (AuthenticationError,RetryExhaustedError,SchemaDriftError,DataUnavailableError,CSVSchemaError,EmptyCSVError,CSVRowError,InvalidCliArgError), listed in full inpython/src/teamspend/__init__.py. Same as the npm package, theopencode/codex/claude-code-personaladapters 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.
teamspend ships a](#csv-import-for-the-history-a-live-api-cant-reach)Model Context Protocolserver 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.
pip install "teamspend-cli[mcp]"
Add it to your MCP client's config (for Claude Desktop,claude_desktop_config.json):
{ "mcpServers": { "teamspend": { "command": "uvx", "args": ["--from", "teamspend-cli", "teamspend-mcp"] } } }
The server exposes one tool,run, that shells out to the publishedteamspendnpm binary with the given arguments plus--json, and returns the parsed JSON result:
run(["--tools", "claude-code-personal,opencode", "--before", "2026-04-01:2026-04-30", "--after", "2026-06-01:2026-06-30"])
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.
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.
- 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--versioncurrently 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 onmainand ships in the next PyPI release.pip show teamspend-clialways reports the real installed version in the meantime.
Claude Desktop / Cursor
Paste into your MCP client config file to install this server.
{
"mcpServers": {
"teamspend": {
"server": {
"command": "uvx",
"args": [
"teamspend-cli"
]
}
}
}
}
McpServers
{
"server": {
"command": "uvx",
"args": [
"teamspend-cli"
]
}
}
Transport
"stdio"
Package
"teamspend-cli"
Registry
"pypi"
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 adiffdoes 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 (](https://github.com/RudrenduPaul/teamspend/blob/HEAD/python/src/teamspend/mcp_server.py)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 byWindows 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.
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.
tokscaleis 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.
codeburnis 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.
Vantagealready 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.
Sign in to leave a review
Use Google, GitHub, or an email account so ratings stay tied to real people.
No reviews posted yet.



