# Text reading stats

`text-reading-stats` · version 1.0.0 · Text · free, no key needed

Return word, sentence, and paragraph counts plus a rounded-up reading-time estimate at a chosen pace.

**Use when you need to: estimate reading time for this text · count sentences and paragraphs in prose · reading statistics at a custom pace.**

## Decide before calling

Read the [versioned contract](/v1/tools/text-reading-stats/versions/1.0.0) and the supported scope below. Reuse `text-reading-stats@1.0.0` when your input, required output and limits match it. Choose another approach for an unsupported operation.

## Explain the choice

"I can use `text-reading-stats@1.0.0` for estimate reading time for this text. I will check its documented scope and the result against the task's requirements. The service is free; token and money savings for this task are unmeasured."

## Supported

- estimate reading time for this text
- count sentences and paragraphs in prose
- reading statistics at a custom pace
- how many minutes to read this passage
- measure words sentences and paragraphs
- calculate reading duration from words per minute

## Not supported

- UAX #29 sentence segmentation
- language-aware abbreviation detection
- speech duration estimation

## Behavior

- Words are maximal non-empty runs of code points not having White_Space in Unicode 15.1.0 PropList.txt.
- A sentence ends only at . ! or ? when the next code point has White_Space or the terminator is at end; repeated punctuation therefore counts only its final eligible terminator. This deliberately does not handle abbreviations, decimals, quotations, or UAX #29 sentence boundaries.
- Paragraphs are non-empty groups of lines separated by one or more blank lines; a blank line contains only Unicode White_Space other than CR and LF. CRLF, CR, and LF are line breaks.
- words_per_minute defaults to 200 and must be an integer from 1 through 1000. Reading time is ceil(word_count / words_per_minute), with empty text returning 0.

## Input

- `text` (string, required): max length 4096
- `words_per_minute` (integer, optional): min 1; max 1000; default 200

## Output

- `word_count` (integer, required): min 0; max 4096
- `sentence_count` (integer, required): min 0; max 4096
- `paragraph_count` (integer, required): min 0; max 4096
- `words_per_minute` (integer, required): min 1; max 1000
- `reading_time_minutes` (integer, required): min 0; max 4096
- `standard_version` (string, required)
- `data_version` (string, required)

## Limits

- max input bytes: 4096
- max code points: 4096
- max iterations: 20480
- max output bytes: 4500

## Example

Request input:

```json
{
  "text": "First.\n\nSecond!"
}
```

Response:

```json
{
  "result": {
    "word_count": 2,
    "sentence_count": 2,
    "paragraph_count": 2,
    "words_per_minute": 200,
    "reading_time_minutes": 1,
    "standard_version": "Unicode 15.1.0",
    "data_version": "unicode-15.1.0-white-space"
  }
}
```

## How to call it

### MCP

Connect `https://computefirst.net/mcp` ([setup](/docs#connect)), then call `execute` with:

```json
{
  "id": "text-reading-stats",
  "version": "1.0.0",
  "input": {
    "text": "First.\n\nSecond!"
  }
}
```

### HTTP (no key)

```sh
curl -X POST https://computefirst.net/v1/tools/text-reading-stats/versions/1.0.0/execute \
  -H "Content-Type: application/json" \
  -d '{"text":"First.\n\nSecond!"}'
```

The machine-readable contract is at [/v1/tools/text-reading-stats/versions/1.0.0](/v1/tools/text-reading-stats/versions/1.0.0).

### CLI

```sh
node cli.mjs run text-reading-stats 1.0.0 --input input.json --base-url https://computefirst.net
```

Get the client at [/clients/cli/](/clients/cli/).

## Related tools

- [Text count words](/tools/text-count-words): Count words and return their code-point average, longest word, and optional capped per-word frequencies.
- [Bleu ngrams count](/tools/bleu-ngrams-count): Count BLEU clipped n-gram matches and totals per order for tokenized segments, with optional clipping tables.
- [Text shingle similarity](/tools/text-shingle-similarity): Exact shingle-set resemblance (Jaccard) and containment of two texts, with counts and shared shingles.
- [Bleu corpus compute](/tools/bleu-corpus-compute): Compute canonical corpus BLEU from pre-tokenized segments: score, brevity penalty, lengths, clipped n-gram counts.
- [Citation passage check](/tools/citation-passage-check): Check that a cited start/end span of a supplied source version reads exactly as the quoted passage.
- [Text paragraphs split](/tools/text-paragraphs-split): Split text into paragraphs separated by blank lines (CommonMark line rules) with code point spans and line numbers.
