# Mezura

> Counts the lines of a codebase quickly and accurately, along with user-defined keywords like classes and structs. Tracks how the figures move between runs, and between any two git revisions. Command line program, library and MCP server.

- **Type:** MCP server
- **Install:** `agentstack add mcp-subamanis-mezura`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [subamanis](https://agentstack.voostack.com/s/subamanis)
- **Installs:** 0
- **Category:** [Data & Analytics](https://agentstack.voostack.com/c/data-and-analytics)
- **Latest version:** 0.1.0
- **License:** Apache-2.0
- **Upstream author:** [subamanis](https://github.com/subamanis)
- **Source:** https://github.com/subamanis/mezura

## Install

```sh
agentstack add mcp-subamanis-mezura
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## 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 `.m` is 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 in `language_conflicts.txt`, or per-project through its configuration, or `--force-language` for 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 `.d` files 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.** `--explain` shows one file line by line with the verdict for each
  line, for checking a count that looks wrong. See `--explain` in [COMMANDS.md](https://github.com/subamanis/mezura/blob/HEAD/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](https://subamanis.github.io/mezura/theme-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
```bash
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:
```bash
cargo build --release
```

### 3. Download the prebuilt binary
Grab the one for your platform from the [latest release](https://github.com/subamanis/mezura/releases/latest).

## Usage

### Quick start

```bash
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](https://github.com/subamanis/mezura/blob/HEAD/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:

```bash
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](https://github.com/subamanis/mezura/blob/HEAD/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](https://github.com/subamanis/mezura/blob/HEAD/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.

```bash
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](https://github.com/subamanis)
- **Source:** [subamanis/mezura](https://github.com/subamanis/mezura)
- **License:** Apache-2.0

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-subamanis-mezura
- Seller: https://agentstack.voostack.com/s/subamanis
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
