Install
$ agentstack add mcp-subamanis-mezura ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
mezura
[](https://loc-conformance.github.io/linejudge/) [](https://github.com/subamanis/mezura/actions/workflows/ci.yml) [](https://crates.io/crates/mezura) [](#license)
__mezura__ counts the lines of a codebase quickly and accurately, along with user-defined keywords like classes and structs. It tracks how the figures move between runs, and between any two git revisions. It lets you decide what counts as what, and how the report looks. The figures can be grouped by language, by module and by file. Windows, Linux and macOS binaries are built and tested on every release.
The whole Linux kernel (some languages were cut for screenshot purposes):
Table of contents
- [Why mezura](#why-mezura)
- [Installation](#installation)
- [Usage](#usage)
- [Quick start](#quick-start)
- [Commands](#commands)
- [Modules](#modules)
- [Layouts](#layouts)
- [What is counted](#what-is-counted)
- [The counting model](#the-counting-model)
- [What is skipped](#what-is-skipped)
- [Taking the result elsewhere](#taking-the-result-elsewhere)
- [Markdown output](#markdown-output)
- [JSON output](#json-output)
- [Coding agents (MCP)](#coding-agents-mcp)
- [As a library](#as-a-library)
- [Tracking growth](#tracking-growth)
- [Logs and history](#logs-and-history)
- [Diffs](#diffs)
- [Configuration](#configuration)
- [Your own configurations](#your-own-configurations)
- [The settings of a project](#the-settings-of-a-project)
- [The data directory](#the-data-directory)
- [Themes](#themes)
- [Supported languages](#supported-languages)
- [Accuracy and limitations](#accuracy-and-limitations)
- [Performance](#performance)
- [Threads and phase timing](#threads-and-phase-timing)
- [Windows and antivirus](#windows-and-antivirus)
- [Contributing](#contributing)
- [License](#license)
Why mezura
Things it does that most counters do not:
- Ensures the right language for each file. When two languages claim one extension, the way
.mis MATLAB and Objective-C and Mercury all at once, every file is identified by its own content: a#!line first, then heuristics on its content. And you always have the last word: set your preferences globally inlanguage_conflicts.txt, or per-project through its configuration, or--force-languagefor one run, or even per module in the same run. See [Supported languages](#supported-languages). - Discards non-code files with a matching extension (no more Make dependency
.dfiles counted as the D language!). Alongside the minified and generated files that are skipped by default, they are reported as skipped. See [What is skipped](#what-is-skipped). - Keyword counting. Occurrences of words you pick per language, classes, structs, traits,
anything, counted only where they appear as code and never inside a string or a comment.
- Nested languages. The `
and` blocks of HTML, Vue, Svelte and Astro files are
counted as the distinct languages they hold.
- Modules. Give a name to parts of a project and the report is grouped by these parts as well as by
language. This way you can split your project into e.g. Frontend and Backend and Tests and see distinct reports for each module in the same table in the same run. See [Modules](#modules).
- Track the history of your codebase. Log runs and compare against earlier ones, or diff against a git revision. See [Tracking growth](#tracking-growth).
- Diff view of git revisions or json files. You can see the diff between the current state and a git revision, or between two revisions, or between an earlier run that was saved in a json file. See [Diffs](#diffs).
- Two counting models to pick from. By default a line counts by what it says: a blank line inside a comment
is blank, a lone } is neither code nor comment. --counting region switches to the model most other counters use, so the behavior matches theirs. See [The counting model](#the-counting-model).
- Per-line explanations.
--explainshows one file line by line with the verdict for each
line, for checking a count that looks wrong. See --explain in COMMANDS.md.
- Very customizable output. You have a lot of control about how mezura counts, and also about how
it presents the results to you. You don't like the layout? You find it very busy with many sections? You don't want the animations? You can change everything. See [Commands](#commands).
- Themes. Everything printed can be styled and colored: 78 tokens, 13 bundled themes, and an interactive web editor to experiment. See [Themes](#themes).
- Output for programs. One JSON document with
--output json, and an MCP server so a coding
assistant can run mezura itself. See [Taking the result elsewhere](#taking-the-result-elsewhere).
- Data driven. All the files, languages and the settings mezura uses are extracted to your machine, where they can be inspected, changed, or extended very easily. See [The data directory](#the-data-directory).
It's also the most accurate at what it measures. See [Accuracy and limitations](#accuracy-and-limitations).
Installation
The only thing you need is the binary, and there are 3 ways to get it:
1. Install it with cargo
cargo install mezura
To update an existing installation to the latest version, just run the same command again: it will fetch the newest published version, rebuild, and replace the old binary.
2. Build it yourself
After cloning or downloading the repo:
cargo build --release
3. Download the prebuilt binary
Grab the one for your platform from the latest release.
Usage
Quick start
mezura # count the current directory
mezura ./src # count one directory
mezura ./src, ./tests # count two; commas separate targets
mezura frontend=./web backend=./api # group the report by part (modules)
mezura ./src --diff main # what changed since main
mezura --by-file # show results for every file separately
mezura src/main.rs --explain # why each line was counted the way it was
In Windows PowerShell a comma needs a backtick before it, or the whole list needs quotation marks: mezura "./src, ./tests".
Files that a .gitignore ignores are skipped by default, and so are minified and generated files, so build artifacts and dependencies do not pollute the stats. See [What is skipped](#what-is-skipped).
A run can be stopped at any time with Ctrl-C: the moving lines never hide the cursor or take over the screen, so the terminal is left as it was.
Commands
One line per command, grouped by what it touches:
WHAT IS COUNTED
--targets the directories and files to count, and the names to group them under (modules)
--counting whether a line counts by where its words are or by where the line sits
--exclude paths to leave out, as glob patterns
--languages count only these languages and leave every other one out of the report
--exclude-languages count everything except these languages
--force-language count an extension as the language you pick, even if another one claims it
--no-gitignore count the files a .gitignore ignores
--no-ignore-files count the files a .ignore or a .rgignore hides
--search-in-dotted go into directories whose name starts with a dot
--count-minified count the minified files that are left out by default
--count-generated count the generated files that are left out by default
--count-not-code count the non-code files that are left out by default
--no-heuristics never try to automatically resolve the contest when two languages claim the same
extension
--no-shebang identify every file by its name alone, leaving the '#!' line inside it unread
--show-languages print the languages this installation knows, with their extensions, and stop
HOW THE REPORT LOOKS
--layout the shape of the details section: a table, a box, a list, or a matrix of modules
--sort which column the languages are ordered by
--top show only this many languages, and say how many were left out
--by-file give every file its own row, or only the biggest few of each language
--hide parts of the output to leave unprinted
--theme apply a theme, which is a whole look kept in one file
--style override the color and attributes of one kind of printed text
--bar-thickness the character the overview's percentage bar is drawn with
--progress-bar the characters the live progress bar is drawn with
--number-separator the character between the thousands of every printed number
--decimal-separator the character before the decimals of every printed number
--show-themes print the themes this installation holds, each previewed, and stop
--theme-editor open a page for tuning the colors of the report, and stop
TAKING THE RESULT ELSEWHERE
--output text for a person, markdown for a page, or one JSON document for another program
--log append this run to the log of the loaded configuration
COMPARING WITH EARLIER RUNS
--compare how many earlier logged runs to show the difference against
--diff what changed since an earlier run, or between two of them
YOUR DATA DIRECTORY
--save save the flags of this run as a named configuration
--load take the flags of this run from a saved configuration file
--no-default-config ignore the default configuration of this machine
--save-theme save the way this run looks as a named theme
--show-configs print the configurations this installation holds and stop
--restore put the data directory back to what this version ships, and stop
THE SETTINGS OF A PROJECT
--save-local save the flags of this run as the settings of this project
--no-local ignore the settings of the project being counted
TUNING AND DIAGNOSTICS
--explain show one file line by line instead of printing a report
--threads how many threads walk the directories and how many parse the files
--show-faulty-files name the files that could not be parsed, and what went wrong with each
--show-skipped name the files that were left out as minified, generated or not code
THE PROGRAM ITSELF
--help this list, or the full help of the commands you name
--version the version of this binary and the day it was released
--changelog what changed in this version, or in every version with 'full'
Run --help for the full text of one command, or --help full for all of them. The same texts are in COMMANDS.md, so they can be read without a terminal.
Modules
Give a target a name and the report is grouped by that name as well as by language:
mezura frontend=./web backend=./api
mezura ./project tests=./project/tests
Every file belongs to exactly one module and the most specific path wins, so the second example means "the tests there, the rest of the project here". Targets that were not explicitly claimed by a module are shown under a row called (unnamed). A comma continues a module and a space ends it, so tests=./api/tests,./web/tests is one module of two directories.
Each module gets its own block of rows, with its own languages and totals, and the history section then records how each module grew.
--layout matrix crosses them instead, languages down and modules across, one figure per cell.
The full rules (glob patterns, repeated names, ordering) are under --targets in COMMANDS.md.
Layouts
The details section comes in four shapes. table is the default and boxed draws the same figures inside a frame, both of them aligned so a column can be read down. list gives each language a sentence instead, reading left to right, and matrix answers a different question, languages down and modules across.
The four layouts on the same run
--layout table
--layout boxed
--layout list
--layout matrix
--hide takes any part of the output away, whole sections or single columns, and --sort, --top and --by-file decide what the rows are and in what order. They are all listed in COMMANDS.md.
What is counted
The counting model
By default, mezura asks what a line says, not which block it sits inside. A blank line inside a block comment is not a comment, because it documents nothing. A line holding only } or ); is neither code nor comment, because it carries no data and no instruction: those are tokens the language demands, placed wherever your style puts them, and whether the brace goes on its own line is not a fact about how much code you wrote.
So under this model code and comments do not add up to lines. What is left over is grouped as extra, and it is the part of the file that carries nothing. This is the default, and it can be asked for explicitly with --counting content.
Counters that group by region answer the other question, "which block is this line inside", and give the blank line to the comment and the brace to the code. Neither reading is wrong, they answer different questions, and it is worth knowing which one you are reading. For the more conventional region-based counting, run mezura --counting region.
What is skipped
Files and folders named in a .gitignore, .ignore or .rgignore are skipped (see --no-gitignore and --no-ignore-files). Directories whose name starts with a dot are skipped unless --search-in-dotted is given, and .git is never traversed at all.
Three checks on a file's head can also set it aside, each reported above the table with its own count: minified (an average line of 1000 bytes or more), generated (a marker like do not edit or @generated in the first 512 bytes), and not code at all (give-away text listed per extension in language_conflicts.txt, the way a .d dependency file is not the D language and a ProGuard .pro is not Prolog). Each check has its own flag that turns it off: --count-minified, --count-generated, --count-not-code. The not-code check is also off under --no-heuristics. --show-skipped prints the paths, and --explain on such a file says which check set it aside. The reasoning behind the tests is in [Accuracy and limitations](#accuracy-and-limitations).
A path you write out yourself is always counted, even if it is ignored, dotted, a link, minified, generated or not code. The matches of a glob pattern were found by mezura rather than named by you, so those are skipped like any other found path.
Taking the result elsewhere
Markdown output
--output markdown prints the details as a markdown table, for a build step to leave in a pull request or a job summary.
mezura ./src --diff origin/main --output markdown >> $GITHUB_STEP_SUMMARY
The modules, the languages under them and the changed files under those are all rows of the one table, at the depth the printed report draws them at.
It is the report and not a document of its own, so --hide, --sort and --top cut and order it exactly as they do the printed one, and --by-file hangs the changed files under each language. Markdown has one table shape, so --layout has nothing to choose between and is ignored, and the colours, the overview bar and the history section are left out, all three being
…
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: subamanis
- Source: subamanis/mezura
- License: Apache-2.0
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.