Skip to main content

toolbill

Measure the token cost of MCP tool definitions before they enter a model's context window.

PyPI CI Python License: MIT

Why

Every MCP tool definition (its name, description, and JSON schema) is sent to the model on every turn, whether or not the tool is used. Most clients never show you how much that costs.

Four small reference servers add up to 7,994 tokens per turn. One tool alone, sequentialthinking, accounts for 1,005 of them, and more than half of that is its description.

toolbill shows you the bill: per server, per tool, and split into description, schema, and annotations, so you know what to trim or disable. It only measures. It never proxies, rewrites, or changes your setup.

toolbill is a read-only Python CLI and library for auditing MCP server tool definitions. It discovers supported local client configurations, starts local stdio servers, calls tools/list, and reports total and per-tool token counts.

Install and run

python -m pip install toolbill
toolbill audit

By default, audit discovers MCP configs for Claude Desktop, Claude Code, Cursor, VS Code, and GitHub Copilot CLI, and starts their configured stdio servers. The official mcp Python SDK handles the stdio connection and MCP protocol.

Example audit summary:

SERVER               STATUS  TOOLS  TOKENS  % OF TOTAL  HEAVIEST TOOL
filesystem           OK         14   2,852       35.7%  read_media_file (294 tokens)
memory               OK          9   2,408       30.1%  search_nodes (327 tokens)
everything           OK         13   1,729       21.6%  gzip-file-as-resource (249 tokens)
sequential-thinking  OK          1   1,005       12.6%  sequentialthinking (1,005 tokens)
TOTAL                           37   7,994      100.0%  sequentialthinking (1,005 tokens)

Measured on 2026-10-10 against the latest published versions of the four official reference servers. Run the command yourself to reproduce:

toolbill audit --config examples/reference-servers.json --timeout 60

Use --dry-run to see which servers would be launched without running them. HTTP servers are listed as SKIP; HTTP transport is not supported in this release. Command arguments and URL credentials are redacted in dry-run output. Environment variable values are never displayed.

Each server has a 15-second timeout by default. Change it with --timeout SECONDS. A server that fails to launch, initialize, times out, or fails to list tools gets a FAILED row; the audit continues with other servers. Server stderr is suppressed unless --verbose is passed. Failed servers make the CLI exit with status 1.

The summary includes each server's share of total tokens and its heaviest tool. The tool table shows the 10 heaviest tools overall by default. Use --all-tools to show every tool, or --json to print the full report (all servers and tools) as JSON:

toolbill audit --all-tools
toolbill audit --json

To audit a specific config file instead of the discovered configs:

toolbill audit --config ~/.cursor/mcp.json
toolbill audit --config .mcp.json --timeout 30

Python API

import asyncio
from toolbill import audit_config, audit_server

async def main():
    report = await audit_config("~/.cursor/mcp.json")
    print(f"{report.total_tokens:,} tokens across {report.tool_count} tools")

    for server in report.servers:  # sorted, heaviest first
        print(f"{server.name:<16} {server.tokens:>7,} ({server.share:.1%})")
        for tool in server.heaviest(5):
            print(tool.name, tool.tokens, tool.breakdown)

    filesystem = await audit_server(
        command="python",
        args=["my_mcp_server.py"],
        timeout=15,
    )
    print(filesystem.tokens, filesystem.status)

asyncio.run(main())

audit_config(path, *, model="openai", timeout=15, verbose=False, tokenizer=None) returns an AuditReport. audit_server(command, args=None, *, env=None, cwd=None, name=None, model="openai", timeout=15, verbose=False, tokenizer=None) returns a ServerReport. The first release supports the openai model option and uses tiktoken's o200k_base encoding. Pass an object implementing count(text: str) -> int as tokenizer to use a compatible custom counter.

Reports expose total_tokens, tool_count, servers, and lookup by server name (report["github"]). Each server has name, tokens, tool_count, share, status, tools, and heaviest(n). A tool has name, tokens, and a breakdown for description, schema, and annotations. Failed/skipped servers have a safe summary in error and contribute no tokens.

Tokenization details

For each MCP Tool returned by tools/list, toolbill first converts the SDK object to its protocol-field JSON object, omitting absent and null fields. It tokenizes the complete tool definition as compact UTF-8 JSON: recursively sorted object keys, no insignificant whitespace, and non-ASCII characters preserved. No client-specific wrapper or provider framing is added.

Breakdown counts are measured independently: description is counted as its plain text; schema is the compact JSON object containing inputSchema and/or outputSchema; annotations are counted as their compact JSON value. These field counts do not necessarily sum to the complete definition's token count.

tools/list pagination is followed until the server returns no cursor, so each listed tool is counted. Counting measures the tool definitions only; provider framing overhead is not included.

Configuration discovery and safety

The config fixtures in tests/fixtures follow the documented formats for each supported client:

Client Config format and discovery locations Current reference
Claude Desktop mcpServers; platform config (claude_desktop_config.json) Local MCP servers
Claude Code mcpServers; ~/.claude.json MCP reference
Cursor mcpServers; ~/.cursor/mcp.json and project .cursor/mcp.json Cursor MCP docs — configuration format and locations
VS Code servers; user profile mcp.json and workspace .vscode/mcp.json Configuration reference
GitHub Copilot CLI mcpServers; $COPILOT_HOME/mcp-config.json (default ~/.copilot/mcp-config.json) Copilot CLI configuration directory

The portable workspace .mcp.json format (mcpServers) is also discovered once and labeled MCP portable, since more than one client can read it.

MCP servers are executable programs. Review a server configuration before auditing it. --dry-run never starts a server; it omits environment values and redacts credential-looking argument and URL values. The same redaction applies to error output. Server stderr remains hidden by default; --verbose displays it, which may reveal whatever the server itself writes there.

Development

python -m pip install -e ".[test]"
pytest

The GitHub Actions workflow runs the test suite on supported Python versions. See CONTRIBUTING.md for guidelines and CHANGELOG.md for release notes.

License

MIT. See LICENSE.

Metadata

Release files for toolbill 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for toolbill 0.1.2
File Size Uploaded
toolbill-0.1.2.tar.gz 21.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for toolbill 0.1.2
File Interpreter ABI Platform
toolbill-0.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 37.5 kB

Release files / toolbill-0.1.2.tar.gz

Download URL toolbill-0.1.2.tar.gz
Size 21.9 kB
Tags Source
SHA-256 checksum
How to use checksums
7798a76a32343b666b78eb8e07fc2b9d05a4089ee75cf5b46243a859b4a12d49
BLAKE2b-256 checksum
How to use checksums
087fe00a749c0d7b21a6e5f05c17dcf206a45d7edc5ee9b88968986031c97240
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Release files / toolbill-0.1.2-py3-none-any.whl

Download URL toolbill-0.1.2-py3-none-any.whl
Size 15.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d081f56ee11f057d0d6f42c18a803d777b047699327eaf74476bdc03d919fe18
BLAKE2b-256 checksum
How to use checksums
818031739efe8552fb5a8388f3dba1e4caef61fe663664105466eadfdb3ea968
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Release history Release notifications | RSS feed

0.1.3

2 release files

This release

0.1.2 This release

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page