Count Claude Prompt Tokens
Build a CLI script that reports Claude token counts for files in a folder.
Introduction
30 Second Summary
A folder full of documents can hide a surprisingly large request. Without a count upfront, you only discover its size after sending it.
In this project, you will build a reusable report that counts every document in a folder before you send it to Claude. The report compares token totals across models before a paid request.
What You'll Build
You will open a spreadsheet and see a clear token count for every file-model pair before sending a paid prompt.
By the end of this project, you'll have:
- A quick prompt check that prints the token count for a short prompt before you send it.
- A reusable CSV report you can open in a spreadsheet to compare every file across models.
- A count-versus-usage comparison showing how closely the free estimate matches the usage from a real Claude prompt.
- Secret Mission: An optional challenge to push your token-counting skills further.
Are there any prerequisites?
You need Python plus either pip or uv.
You also need an Anthropic API key for the counting requests.
Before We Start
A useful token report begins with a clear source folder. If the source is unclear, the later CSV cannot show which documents were measured.
The Anthropic token counting API is free to use. An API key authorizes each request.
In this step, get ready to:
- Open a terminal session.
- Choose a local folder containing text documents.
- Prepare an Anthropic API key for later use.
Choose your input folder
The script later reads every file in one local folder. That folder becomes the input boundary for your token report.
Finding the full folder location can be fiddly. Dragging the folder into a terminal reveals the exact path.
- Press Cmd+Space (macOS) or the Windows key (Windows) to open your search bar.
- Type terminal into the search field.
- Choose a terminal application from the search results.
- Use Finder (macOS) or File Explorer (Windows) to locate the folder containing the documents you want to measure.
- Select the folder containing your text documents.
- Drag the selected folder from the file browser into the terminal window.
You'll see the folder's full location appear at the terminal prompt. The path has not run as a command.
- Record the displayed location here: path to your documents folder.
- Clear the unrun path by pressing Ctrl+C.
Don't see a folder path?
- Place your file browser beside the terminal window.
- Drag the folder icon itself onto the terminal prompt.
Help me find my input folder's full path.
Prepare your Anthropic API key
Anthropic issues API keys through its web Console in Account Settings. This section keeps your key in a password manager until the later command-line setup.
Credential setup deserves care. You only reveal or retrieve the key long enough to confirm that it is safely stored.
✔️ I already have an API key
An existing key is ready when your password manager contains its full value.
- Open the API key entry in your password manager.
- Confirm that the entry contains the full key without copying it into this project page.
- Close the password manager entry.
Your key remains safely stored for the next setup step.
ⓧ I need to create an API key
- Open the official Anthropic API overview.
- Follow the Claude Console link from the overview.
- Sign in with your Anthropic account.
- Complete any account verification that appears.
- Open Account Settings.
You'll reach the area where Anthropic generates API keys for your account.
- Start creating a new API key.
- Choose a key type in the creation form.
- Choose an expiration that covers this project.
- Generate the key.
You'll see the generated credential after the form completes.
- Store the full key in your password manager.
- Close the key view after saving the credential.
Your API key is now available without being stored in llm yet.
Can't access a full API key?
- Create a new key if your existing entry contains only part of the value.
- Ask your Anthropic account administrator for key creation access if Account Settings does not offer it.
Help me prepare an Anthropic API key safely.
Confirm your starting point
Before you check, which folder location do you expect to appear when you drag your selection into the terminal?
- Return to the terminal from earlier.
- Drag your selected documents folder into the terminal window.
You'll see the folder location appear at the prompt.
- Compare the displayed location with path to your documents folder.
- Confirm that your password manager lists the API key entry without revealing its value.
You're set. The matching path proves your selected documents are reachable from the terminal.
The password manager entry confirms your credential is ready for the next step.
- Clear the folder path from the terminal by pressing Ctrl+C.
Your inputs are ready. Next, you'll install the command-line tools that run the token counter.
Install llm and the Anthropic Plugin
A token report needs a terminal command that can prepare Claude requests before they are sent. LLM provides that command-line foundation.
Support for Anthropic comes through the llm-anthropic plugin. Your API key stays untouched during this installation step.
In this step, get ready to:
- Install the llm command-line tool.
- Add the llm-anthropic plugin.
- Confirm the plugin appears in the installed plugin list.
Prepare the LLM foundation
LLM is distributed as a Python package. Installing it makes the llm command available to your terminal.
- Install LLM into your Python environment by running this command:
pip install llm
What does this command add?
- The pip package installer downloads LLM with its required dependencies.
- The installation exposes the llm command to your terminal.
You'll see package installation activity before the terminal returns to its prompt. A clean return means the installation finished without a reported error.
- Confirm your terminal can find the installed command by running this check:
llm --version
What does this check prove?
This starts the installed CLI. A version number proves that your terminal can find it.
You'll see an installed version number. The base tool is now ready to accept plugins.
Command still unavailable?
- Start a new terminal session so your shell reloads its command paths.
- Follow the official LLM setup guide if your Python environment blocks the installation.
Help me diagnose my LLM installation.
Add the Anthropic plugin
Plugins extend LLM with support for different model providers. Release 0.30 of the Anthropic plugin introduced the token-counting command used later in this project.
- Install the Anthropic plugin into the LLM environment by running this command:
llm install llm-anthropic
How does plugin installation work?
The llm installer places the plugin in the same environment as the base tool. This shared environment lets LLM discover the Anthropic commands.
You'll see package installation activity before the terminal prompt returns. The plugin is then ready for a direct check.
Plugin installation failed?
- Confirm the earlier version check still prints an LLM version.
- Run the plugin installation command again after confirming your internet connection is stable.
Help me install the Anthropic plugin.
Confirm the plugin is loaded
LLM maintains a list of plugins available in its environment. This list provides direct evidence that the Anthropic extension can load.
- Predict whether the Anthropic plugin appears in the installed list.
- Print the installed plugin list by running this command:
llm plugins
What does the plugin list show?
The command asks LLM to load its plugin registry. The output identifies each plugin available to the active LLM installation.
This output is safe to capture because your Anthropic API key has not been stored yet.
You'll see llm-anthropic in the output. Its presence confirms that LLM can load the plugin required for token counting.
Plugin missing from the list?
- Check that the installed package name is spelled llm-anthropic.
- Run the plugin installation command again from the terminal where the earlier version check worked.
Help me find the missing plugin.
You've got the foundation in place: LLM can now load the Anthropic plugin. Next, you'll store your API key before refreshing the current model list.
Configure Anthropic Access
The llm-anthropic plugin is installed. You already confirmed that llm can see it.
Access is the remaining gap. You will store your Anthropic API key in llm.
The model catalog can change over time. Refreshing it gives later counting commands the current choices.
In this step, get ready to:
- Store your Anthropic API key in llm's key store.
- Refresh the current Anthropic model list.
Store your Anthropic API key
An API key lets the plugin authenticate requests to Anthropic. The interactive setup keeps the key out of the command itself.
Credential setup can feel risky, but this prompt accepts your key after the command starts.
- Switch back to the terminal from earlier.
- Start the interactive key setup by running this command:
llm keys set anthropic
How Is the Key Stored?
- The llm keys set command opens the key store's interactive save flow.
- The anthropic name identifies the credential for Anthropic requests.
- Paste your Anthropic API key when you see the Enter key: prompt.
- Press Enter to save the key.
When the command finishes, you will return to your terminal prompt.
You can verify the saved entry by listing key names. This check does not print the credential value.
- Confirm the saved key name by running this command:
llm keys
What Does This Check Show?
The command lists the names in the key store. It keeps their credential values out of the output.
You should see anthropic among the stored key names.
Anthropic Missing From the List?
Rerun the key setup command above. Make sure you press Enter after pasting the key.
If the name still does not appear, help me check why llm is not storing my Anthropic API key.
Good work. The plugin now has a stored Anthropic credential without exposing its value in your check.
Refresh the Anthropic model list
The model list controls which Anthropic models llm can address through the plugin. A refresh retrieves the current catalog before your first count.
Before you run the refresh, do you expect one model name or a list of available models?
- Retrieve the current Anthropic model list by running this command:
llm anthropic refresh
What Does the Refresh Do?
- The command asks the plugin to retrieve the current Anthropic model list.
- A successful request confirms that the stored key can authenticate the plugin.
You should see a list of Anthropic models in the terminal. That output confirms the refresh completed.
Model List Not Appearing?
If the refresh reports an authentication problem, rerun the key setup command above with your current API key.
If the Anthropic subcommand is unavailable, return to the plugin check from the previous step. Confirm that llm-anthropic is still listed.
If the refresh still fails, help me troubleshoot the Anthropic model refresh.
That is the access layer ready. llm now has a stored Anthropic key plus a current model list.
Next up, you will count the tokens in a short prompt before sending anything to Claude.
Test Token Counting
Your stored key and refreshed model list give llm access to Anthropic's current models. Before you build a report for an entire folder, you need proof that one prompt can be counted successfully.
A short test gives you a known input with a simple output from the token counting API. Once the terminal prints the count, you know the counting path is ready for the folder-wide script.
In this step, get ready to:
- Run a short prompt through the token counting command.
- Confirm that the resulting token count appears in the terminal.
Start with a controlled prompt
The count command measures the input before requesting a generated response. This keeps the test focused on the number of tokens in the prompt.
Before you run this, what kind of output do you expect from a command that only counts tokens?
- Count the documented prompt by running this command:
llm anthropic count 'Fun facts about walruses' -m claude-opus-5
What does this command do?
- The count subcommand sends the quoted prompt to the token counting API.
- The -m option selects claude-opus-5 for this count.
- The API returns the number of input tokens without generating a response.
- The counting request costs $0.
You should see a single integer printed on its own line. For this documented example, the output is 15.
That first count is working. You can now measure prompt size before paying to generate a response.
No token count in the terminal?
- Check that the prompt has one opening quote and one closing quote.
- Confirm that claude-opus-5 appears in the model list you refreshed earlier.
- Replace the model value with an available model ID from that list if needed.
Help me troubleshoot the token counting command.
Interpret the terminal output
A standalone integer is the success signal for this command. It confirms that the prompt reached the counting API.
- Locate the final line of the terminal output.
You should see the token count printed as a number. The output contains no generated answer because this request only performs counting.
Your token counting setup now works for a single prompt. Next, you'll apply it to every document in your selected folder and save the results as a CSV report.
Create the Token Report Script
Your one-prompt test proved that token counting works. Now you need the same check to cover every document in your selected folder.
A Python script can build every file-and-model combination automatically. It can collect each result in a reusable CSV report.
In this step, get ready to:
- Write a reusable script that counts each document with every selected Anthropic model.
- Generate a token report with one row for each file-and-model combination.
- Open the finished report in a spreadsheet.
Write the batch counter
The script accepts your input folder plus one or more model names. It passes each document to the token counting command through standard input.
- Switch back to the terminal from earlier.
- Move to your Desktop by running this command:
cd ~/Desktop
- Open a plain-text editor that is already installed on your computer.
- Create a new file on your Desktop.
- Name the file count_tokens.py.
- Paste this code into count_tokens.py:
import argparse, csv, subprocess
from pathlib import Path
# Collect the folder and model names supplied at runtime
parser = argparse.ArgumentParser(description="Count Anthropic prompt tokens.")
parser.add_argument("input_folder", type=Path)
parser.add_argument("models", nargs="+")
args = parser.parse_args()
output_path = Path("token_report.csv")
# Send one document and model combination to the token counting command
def count_tokens(file_path, model):
result = subprocess.run(
["llm", "anthropic", "count", "-m", model],
input=file_path.read_text(encoding="utf-8"),
text=True, capture_output=True, check=True,
)
return int(result.stdout.strip())
# Write one CSV row for every file and model combination
files = sorted(path for path in args.input_folder.iterdir() if path.is_file())
with output_path.open("w", newline="", encoding="utf-8") as report:
writer = csv.writer(report)
writer.writerow(["file", "model", "tokens"])
for file_path in files:
for model in args.models:
tokens = count_tokens(file_path, model)
writer.writerow([file_path.name, model, tokens])
print(f"{file_path.name} | {model} | {tokens}")
print(f"Wrote {output_path}")
What does this code do?
- The command-line arguments keep the script reusable. You can supply a different folder or model list each time.
- The count_tokens() function sends a document to llm anthropic count for one model. The command returns an integer token count.
- The nested loops cover every file-and-model combination. Each result becomes one row in token_report.csv.
- Save count_tokens.py on your Desktop.
✔️ Awesome, I've got everything!
Your script is ready. Double check that count_tokens.py is saved on your Desktop.
ⓧ I'd like to double check the full code
import argparse, csv, subprocess
from pathlib import Path
# Collect the folder and model names supplied at runtime
parser = argparse.ArgumentParser(description="Count Anthropic prompt tokens.")
parser.add_argument("input_folder", type=Path)
parser.add_argument("models", nargs="+")
args = parser.parse_args()
output_path = Path("token_report.csv")
# Send one document and model combination to the token counting command
def count_tokens(file_path, model):
result = subprocess.run(
["llm", "anthropic", "count", "-m", model],
input=file_path.read_text(encoding="utf-8"),
text=True, capture_output=True, check=True,
)
return int(result.stdout.strip())
# Write one CSV row for every file and model combination
files = sorted(path for path in args.input_folder.iterdir() if path.is_file())
with output_path.open("w", newline="", encoding="utf-8") as report:
writer = csv.writer(report)
writer.writerow(["file", "model", "tokens"])
for file_path in files:
for model in args.models:
tokens = count_tokens(file_path, model)
writer.writerow([file_path.name, model, tokens])
print(f"{file_path.name} | {model} | {tokens}")
print(f"Wrote {output_path}")
Generate and open the report
Each model name must match an entry from the refreshed Anthropic model list. The folder path tells the script which documents belong in the report.
- Set the folder path to path to your input-documents folder.
- Set the models to space-separated Anthropic model names.
Before you run the script, how many file-and-model combinations do you expect it to count?
- Generate token_report.csv by running this command:
python count_tokens.py "[[INPUT_FOLDER="path to your input-documents folder"]]" [[ANTHROPIC_MODELS="space-separated Anthropic model names"]]
You'll see one line for each file-and-model combination. The final line confirms that the script wrote token_report.csv.
Report not generated?
Check that the input folder path points to the selected folder. Keep the surrounding quotation marks when the path contains spaces.
Copy each model name exactly from the refreshed model list. A decoding problem means the folder contains a file that is not UTF-8 text.
Help me debug my token report script.
A CSV turns the terminal results into a table. The number of data rows equals the number of files multiplied by the number of selected models.
Before you open the report, do you expect its row count to match your prediction?
- Press Cmd+Space (macOS) or the Windows key (Windows) to open your search bar.
- Type Finder (macOS) or File Explorer (Windows).
- Press Enter.
- Select Desktop in the sidebar.
- Double-click token_report.csv to open it in your spreadsheet application.
You'll see the headers file, model, and tokens. Every input document appears once for each selected model.
That's the batch workflow working. You can now inspect a whole folder before deciding which prompts to send.
Your reusable token report is ready. Next up, you'll send one prompt for real and compare its reported usage with your count.
Compare a Real Prompt
Your CSV has turned a folder of documents into a pre-send token forecast. A forecast becomes trustworthy when you compare it with one real request.
This step sends one document to Anthropic through llm. You will compare the response's reported input usage with the matching row in token_report.csv.
This is the first paid request in the project. The project uses one prompt, so the expected cost is only cents.
In this step, get ready to:
- Select one file and model from your CSV report.
- Send the same input to Anthropic with usage reporting.
- Compare the reported input usage with the pre-send count.
Choose one report row
A controlled comparison uses the same document with the same model. One existing row in your report provides both values.
- Record the model from one text-file row here: your selected Anthropic model.
- Record the matching document path here: path/to/your/input-document.txt.
- Record the row's token count here: your pre-send token count.
Recount the exact prompt
The count command calls Anthropic's free token counting endpoint. Repeating the count confirms that your chosen file still matches its row in the report.
- Switch back to the terminal from earlier.
- Verify the selected file and model by running this command:
cat "[[DOCUMENT_PATH="path/to/your/input-document.txt"]]" | llm anthropic count -m "[[ANTHROPIC_MODEL="your selected Anthropic model"]]"
What does this command do?
- The cat command reads the selected document into the pipeline.
- The llm anthropic count command measures the request without sending it to the model.
- The -m option applies the model recorded from your CSV row.
- Compare the printed number with your pre-send token count.
You should see the same count as the selected row in token_report.csv. This confirms that the file and model are ready for a fair comparison.
Does the count differ from the CSV?
Check that the document path points to the same file used by count_tokens.py. A file edit after generating the report changes its count.
Check that the selected model exactly matches the model column in the CSV row.
Help me compare my recount with the matching CSV row.
Send and compare the real prompt
A fair test keeps the document and model unchanged. The -u option adds the request's token usage after the response.
Before you send this, do you expect the reported input usage to match the pre-send count exactly or land close to it?
- Send the selected document to the same model with usage reporting by running:
cat "[[DOCUMENT_PATH="path/to/your/input-document.txt"]]" | llm -m "[[ANTHROPIC_MODEL="your selected Anthropic model"]]" -u
What does this command do?
- The llm -m command sends the document content to the selected model.
- The -u option prints the request's usage after the response.
- The input figure is the one to compare with your pre-send count. The output figure measures the model's response.
You will see Claude's response followed by a Token usage summary. The reported input figure should land close to the count from your CSV row.
- Record the reported input total here: your reported input token usage.
- Compare your reported input token usage with your pre-send token count.
That closes the loop: your CSV now has evidence behind it. You can use the report to estimate prompt size before future paid requests.
Missing usage or seeing a large difference?
Check that the send command ends with -u. Without that flag, the response does not include the usage summary.
Confirm that both commands used the same document path. Confirm that both commands used the same model.
Help me compare my pre-send count with my real prompt usage.
You have now tested your report against a real request. Your reusable script can estimate prompt size before the paid call begins.
Secret mission
Audit Your Token Report
Your report already counts every file across your selected models. In this challenge, you will audit the largest file-model pair. You will turn that audit into a same-model preflight rule for future prompt jobs.
Clean Up Your Resources
Clean Up Your Resources
This project leaves no running cloud resources or ongoing charges. Decide whether to keep your reusable files, pause until your next token-counting job, or remove the project outputs.
Resources you used:
- Stored Anthropic API key in llm's key store.
- Reusable token-counting script named count_tokens.py.
- Generated CSV report named token_report.csv.
Keep everything running
No action is needed. Choose this option if you want to count more document folders or compare more models later.
- Keep count_tokens.py as your reusable pre-send counting tool.
- Keep token_report.csv as a record of your latest counts.
- Keep the stored Anthropic API key only on a private machine that you control.
Pause - I'll come back to this later
Close the tools you used while preserving the script and report. There is no running server or background process to stop.
- Close the spreadsheet displaying token_report.csv.
- Close the terminal from earlier.
- Leave count_tokens.py in its current location for your next prompt job.
- Keep the stored Anthropic API key only if this is your private machine.
Delete - I don't want to use this again
Deletion is permanent, so your selected input-documents folder stays untouched. This removes only count_tokens.py, token_report.csv, and the stored Anthropic API key.
- Remove the stored Anthropic API key with llm's key-management tools.
- Confirm the Anthropic API key is absent from llm's key store.
macOS
- Use Finder to return to the folder containing count_tokens.py.
- Use Finder to permanently delete count_tokens.py.
- Use Finder to permanently delete token_report.csv.
- Confirm neither file remains in that folder.
Windows
- Use File Explorer to return to the folder containing count_tokens.py.
- Use File Explorer to permanently delete count_tokens.py.
- Use File Explorer to permanently delete token_report.csv.
- Confirm neither file remains in that folder.
The llm command-line tool and llm-anthropic plugin remain installed for future projects.
Nice Work!
Nice Work!
You did it! You built a reusable token-counting workflow for a folder of documents. Your CSV report now shows the expected input size for each selected Anthropic model before you send a prompt.
You've learned how to:
- Prepared the llm CLI with the llm-anthropic plugin for current Anthropic models. Stored your API key in llm's key store.
- Built count_tokens.py to count every input document for each selected model. Generated the reusable token_report.csv report for spreadsheet review.
- Sent one prompt for real. Compared its reported usage with your pre-send token count.
- Secret Mission: Extended your token-counting workflow through an optional challenge.
Ready to quiz yourself?