upfront
See how many tokens your MCP servers, skills and instruction files cost a coding agent before you type a word, and which tools will break in Claude Code, Codex, Gemini CLI or OpenCode.
The problem
"Claude Code sends 33k tokens before reading the prompt; OpenCode sends 7k" — Hacker News, 706 points; finding out took a logging proxy.
Every connected MCP server puts all of its tool schemas into the context, every skill adds its
description, and AGENTS.md / CLAUDE.md ride along on every request. Usage limits arrive early,
and Codex starts dropping skills (codex#19679)
and MCP tools (codex#44308) once budgets run
out. Claude Code's /context shows this for Claude Code only; OpenCode closed the request as
not planned.
Demo
$ uv run upfront examples/demo --yes --top 2 # in a clone of this repository
upfront 0.1.0 · examples/demo · tokens o200k_base
claude-code ≈ 6,786 before your first prompt
mcp filesystem (14 tools, project) ≈ 2,751
read_media_file ≈ 285
read_text_file ≈ 251
mcp memory (9 tools, project) ≈ 2,365
create_entities ≈ 349
search_nodes ≈ 320
mcp everything (13 tools, project) ≈ 1,602
gzip-file-as-resource ≈ 239
get-structured-content ≈ 186
skills (2, name + description) ≈ 33 bodies ≈ 48 load on demand
CLAUDE.md ≈ 35
...
compatibility
error codex issue-scenarios.files.read: 'files.read' (10 chars) is not a valid OpenAI function name
[openai-tool-name] https://github.com/openai/openai-python/blob/main/src/openai/types/shared_params/function_definition.py
The demo's servers replay tools/list snapshots of the official
filesystem, memory and everything reference
servers (1.0.0), so the numbers above are what those servers really cost.
Install
uvx --from git+https://github.com/thanatchon36/upfront upfront # run from your project, no install
pip install upfront # once v0.1.0 is on PyPI
Python 3.11+. Then, in a project:
upfront # skills, instruction files and the list of servers; starts nothing
upfront --yes # also start/connect to each MCP server and count its tools
Features
- Four harnesses, both scopes. Reads Claude Code, Codex, Gemini CLI and OpenCode configs from the project and your home directory, including
${VAR:-default}expansion and JSONC. - Real tool lists. Talks to every stdio, Streamable HTTP and SSE server with the official MCP SDK, follows pagination, and reports failures (missing command, timeout, "auth required") per server instead of crashing.
- Where the tokens go. Per server and per tool, skill metadata separately from skill bodies, and every instruction file.
- Compatibility checks with sources. Tool names against OpenAI, Anthropic and Gemini rules,
$refparameters in Claude Code, non-standard formats in OpenCode, and Codex's skills budget. Every finding links the documentation or open issue it comes from. - CI-friendly.
--json,--budget Nand--strictexit codes, and--tools-fileto check a savedtools/listwithout starting anything. - Safe by default. Nothing is launched without consent: it asks in a terminal and needs
--yeselsewhere. It only ever callstools/list.
How it compares
| upfront | Claude Code /context |
mcp-assert | ccusage | |
|---|---|---|---|---|
| Up-front cost of MCP tools, skills, instruction files | yes, per harness | yes, Claude Code only | no | no |
| Works for Codex, Gemini CLI, OpenCode | yes | no | n/a | n/a |
| Per-client schema compatibility | yes, 6 sourced rules | no | no; 24 usability lint rules (descriptions, nesting) | no |
| Tests tool behaviour | no | no | yes (assertions, fuzzing) | no |
| Actual spend from past sessions | no | /usage |
no | yes |
Use /context inside Claude Code, mcp-assert to test what your tools do, and
ccusage to see what you've already spent. upfront answers "what will each agent load, and what
breaks where" before you start.
How it works
- Discover: parse each harness's documented config files (concepts).
- Fetch: with consent, start each distinct server once (from the project directory, like the agent) and page through
tools/list. - Count: tokenize each tool's wire JSON with
o200k_base; skill metadata and bodies separately; instruction files whole. - Check: run the per-client rules (table).
More: quickstart · concepts · FAQ · API · decisions
Limitations
- Estimates. One tokenizer for every model; vendors' counts differ, and clients add their own framing around tools (ADR-0003).
- Not the vendor's system prompt. Only what you add is measured.
- Lazy loading isn't modelled. Claude Code's tool search and OpenCode's lazy MCP loading defer some definitions; upfront reports their full cost.
- No OAuth. Remote servers that need a login show "auth required; not measured". Headers from your config are sent; OAuth flows are not run.
- Root-level instruction files only, and only the four CLI harnesses above (no Cursor or Windsurf yet).
- Codex's 2% skills budget depends on the model's window; upfront checks the documented 8,000-character fallback.
Roadmap
- v0.2: exact counts via vendor token-count APIs (opt-in), a
--fixproxy that rewrites schemas per client, Cursor and Windsurf configs. - v0.3:
upfront diffbetween git refs for MCP server pull requests, and a GitHub Action.
Contributing
Bug reports with a config that reproduces the problem help most. See CONTRIBUTING.md; compatibility rules need a public source.
License
Metadata
Release files for upfront 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| upfront-0.1.0.tar.gz | 366.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| upfront-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 386.6 kB
Release files / upfront-0.1.0.tar.gz
| Download URL | upfront-0.1.0.tar.gz |
|---|---|
| Size | 366.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1cb74050108ba72b0f6a97c017044d3758f1a604afe8779cc1d47c1bf75e7be0
|
|
BLAKE2b-256 checksum How to use checksums |
e955d25f3f2683a9fee6e61a6a3bc1cc2a9d18d01df704522028729c7f083a68
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.
Transparency logRelease files / upfront-0.1.0-py3-none-any.whl
| Download URL | upfront-0.1.0-py3-none-any.whl |
|---|---|
| Size | 19.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5ff4a52c41441b46ae1d303a3274493fab41f522b6a82ef8bbe6325178e5c7e9
|
|
BLAKE2b-256 checksum How to use checksums |
86ae68634abb1c2070ccb9865c09f79fb65f3370e58226902c64c9091e3de3b6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.
Transparency log