Skip to main content
Glama
mcp-text-stats

mcp-text-stats

by Fastunbeaten

mcp-text-stats

只回数字、不回正文的文本统计 MCP 服务器。

一个极小的 MCP 服务器(stdio 传输),对文件或文本给出行数、汉字数、词数、字节数等统计口径。 结果里只有数字、路径与口径说明,绝不返回任何文件正文片段。

  • 纯 JavaScript(ESM),单文件实现:index.mjs

  • 唯一运行时依赖:@modelcontextprotocol/sdk@1.32.2(精确锁版本)

  • 零第三方分词依赖:分词 / 字素 / 断句全部使用 Node 内置 Intl.Segmenter,脚本分类使用 Unicode 属性正则

  • 不做 TypeScript 构建,运行时不联网

  • 无状态:同一输入必得同一输出,不含时间戳与随机数


1. 功能与统计口径

count_text 工具返回每个文件的下列指标(以及全部文件的汇总 totals):

指标

口径定义

lines

物理行数,与 POSIX wc -l 语义一致:lines = 换行符个数 + (文件末尾存在非空内容则再加 1)。\n 计一个换行、\r\n 计一个换行(不是两个);空行计入;若文件以换行结尾,末尾不额外产生一个空行;空文件 lines = 0。

paragraphs

段落数:按空行分隔的非空块数。

sentences

句子数:Intl.Segmenter(locale, { granularity: 'sentence' }) 的段数。

words

词数:Intl.Segmenter(locale, { granularity: 'word' }) 中 isWordLike 的段数(近似值,尤其对 CJK)。CJK 默认不返回(words = 0),需 wordsForCjk: true,此时 wordsApproximate = true。

graphemes

字素簇数:Intl.Segmenter(undefined, { granularity: 'grapheme' }) 段数(emoji 组合 / 变体选择符算 1)。

codepoints

汉字数等码点级指标:[...text].length,即 Unicode 码点数(一个汉字 = 1)。

utf16Units

UTF-16 代码单元数:text.length。

han

汉字数:Unicode 属性正则 \p{Script=Han} 按码点计数。

kana / hangul

假名(\p{Script=Hiragana} + \p{Script=Katakana})与谚文(\p{Script=Hangul})码点数。

latin / cyrillic / arabic

拉丁 / 西里尔 / 阿拉伯文码点数。

letters / digits / spaces / punctuation / symbols

依次为 \p{L} / \p{Nd} / U+0020 / \p{P} / \p{S} 的计数。

nonWhitespace

去掉所有空白字符后的码点数。

bytes

文件字节数(UTF-8 编码后的长度)。

bom

是否存在 UTF-8 BOM(EF BB BF)。bom = true 时 BOM 不计入任何字符数(统计前剥离)。

其它行为:

  • 编码:只支持 UTF-8 纯文本(txt / md / json / csv / log / 源码等)。用 TextDecoder('utf-8', { fatal: true }) 解码,失败则该文件写入 warning decode_failed,不中断整批。

  • 二进制格式:pdf / docx / xlsx / 图片 / 压缩包等扩展名不统计,写入 warning unsupported_format。

  • 大文件降级:单文件 > maxBytes(默认 70MB)不读取(file_too_large);> maxBytesForWordCount(默认 20MB)仍统计字符级指标,但跳过 words 与 sentences(skipped_word_segmentation)。

  • 目录递归:自实现的极简 glob(支持 ** 与 *,无第三方依赖)按 include / exclude 过滤,只收集文本类扩展名;单次任务最多 200 个文件,超出截断并写 warning too_many_files。

  • 符号链接一律拒绝:既不跟随、也不统计,请传入真实文件路径(warning symlink_rejected)。Windows 目录联接(junction / mount point)同样按链接处理并被拒绝。

  • 服务端硬上限:maxBytes 上限 200MB、maxBytesForWordCount 上限 64MB;模型传入更大值会被自动钳制(warning max_bytes_clamped)。


Related MCP server: chinese-char-counter-mcp

2. 安装与运行

npm install          # 安装 @modelcontextprotocol/sdk@1.32.2
npm start            # 等价于 node index.mjs(stdio 传输)

直接运行:

node /absolute/path/to/mcp-text-stats/index.mjs

MCP 客户端配置示例(stdio)。任何兼容 MCP 的客户端通用(如 Claude Desktop):

{
  "mcpServers": {
    "text-stats": {
      "command": "node",
      "args": ["/absolute/path/to/mcp-text-stats/index.mjs"],
      "env": {
        "TEXT_STATS_ROOTS": "/absolute/path/to/allowed/root"
      }
    }
  }
}

Windows 下 env 中的路径用正斜杠或双反斜杠均可;TEXT_STATS_ROOTS 支持用 ;(也接受 , 与换行)分隔多个绝对路径。

环境变量 TEXT_STATS_ROOTS

服务端固定白名单,模型传入的任何参数都不能放宽这个边界。

  • 值为分号分隔的绝对路径白名单,例如 /srv/work/tools;/srv/work/data(Windows 用 ;,也接受 , 与换行)。

  • 判定方式:先 path.resolve 规范化,再判断目标是否等于根目录或位于根目录之下(Windows 下大小写不敏感)。

  • 不设置(或设为空)时一律拒绝所有路径:每个路径都会得到 outside_allowed_roots 警告且不会被读取。这是安全默认,请显式配置后再使用。

  • 不在白名单内的路径同样不统计,写入 warning outside_allowed_roots。


3. 使用

工具名:count_text

3.1 输入参数

参数

类型

默认

说明

paths

string[]

—

要统计的文件路径数组(可含目录);与 text 二选一。目录会递归并按 include / exclude 过滤。

text

string

—

直接统计一段文本;与 paths 二选一。

unit

'grapheme' | 'codepoint' | 'utf16'

'grapheme'

字符计量单位。字符级指标都会给出,rules.unit 反映该选择。

language

'auto' | 'zh' | 'ja' | 'ko' | 'en'

'auto'

分词 / 断句所用 locale。auto 时文本含 CJK 用 zh,否则 und。

wordsForCjk

boolean

false

中文 / 日文 / 韩文是否也返回分词数(近似)。

include

string[]

[]

目录递归时的包含模式(支持 ** 与 *)。

exclude

string[]

[]

目录递归时的排除模式(支持 ** 与 *)。

maxBytes

number

73400320(70MB)

单文件字节数上限,超过则不读取(warning file_too_large)。服务端硬上限 200MB,超过会被钳制。

maxBytesForWordCount

number

20971520(20MB)

单文件字节数上限,超过则跳过 words 与 sentences(warning skipped_word_segmentation)。服务端硬上限 64MB,超过会被钳制。

3.2 返回结构

只含数字、路径与口径说明,没有正文:

{
  "files": [
    {
      "path": "/absolute/path/to/example.txt",
      "bytes": 42, "bom": false,
      "lines": 1, "paragraphs": 1, "sentences": 2,
      "words": 0, "wordsApproximate": false,
      "graphemes": 14, "codepoints": 14, "utf16Units": 14,
      "han": 12, "kana": 0, "hangul": 0,
      "latin": 0, "cyrillic": 0, "arabic": 0,
      "letters": 12, "digits": 0, "spaces": 0,
      "punctuation": 2, "symbols": 0, "nonWhitespace": 14
    }
  ],
  "totals": { "…": "同上各字段求和" },
  "rules": {
    "unit": "grapheme",
    "lines": "物理行数:与 wc -l 一致……",
    "bom": "检测 UTF-8 BOM(EF BB BF)……",
    "words": "words = Intl.Segmenter……",
    "binaryFormats": "本期只支持 UTF-8 纯文本……"
  },
  "warnings": []
}

files[].path 为规范化后的绝对路径;text 模式下的伪路径为 (inline text)。


4. 注意事项

  1. 只回统计数字,不回文件正文。 返回体里只有数字、路径与口径说明,不会出现任何一行原文。

  2. 返回体含绝对路径,会暴露本机目录结构。 对外共享工具输出前请自行脱敏。

  3. 必须位于 TEXT_STATS_ROOTS 白名单之内,否则只会得到 outside_allowed_roots 警告,文件不会被读取。

  4. 不设置 TEXT_STATS_ROOTS 则一律拒绝(安全默认):所有路径都会被拒绝并给出 outside_allowed_roots。

  5. 非 UTF-8 文件会被跳过,并给出 decode_failed 警告,不会中断整批任务。

  6. 大文件有上限:单文件 > 70MB 不读取;> 20MB 跳过分词与断句统计(仍给出字符级指标)。

  7. 二进制扩展名不支持(pdf / docx / xlsx / 图片 / 压缩包等),需先抽取为文本再统计。

  8. 单任务最多 200 个文件,超出则截断并给出 too_many_files 警告。

  9. 任何符号链接一律拒绝:既不跟随、也不统计;请传入真实文件路径。直接传入软链接时给出 warning symlink_rejected,其中只包含链接自身的路径,不解析链接目标。Windows 目录联接(junction / mount point)同样被拒绝;穿过链接的路径(如 root/linkdir/file.txt)也会被拒绝。

  10. 服务端对 maxBytes / maxBytesForWordCount 有硬上限(200MB / 64MB):模型传入更大的值会被自动钳制到上限,并给出 warning max_bytes_clamped;请通过 TEXT_STATS_ROOTS 控制可访问范围。

warning code 一览

code

含义

outside_allowed_roots

路径不在白名单根目录之下,未统计

file_unreadable

文件不存在或无权限,已跳过

file_too_large

超过 maxBytes,未读取

skipped_word_segmentation

超过 maxBytesForWordCount,跳过 words / sentences

decode_failed

UTF-8 解码失败,已跳过该文件

unsupported_format

二进制 / 多格式文件,需先抽取为文本

too_many_files

超过 200 个文件上限,已截断

symlink_rejected

路径是符号链接,一律拒绝(不跟随、不统计)

max_bytes_clamped

请求的 maxBytes / maxBytesForWordCount 超过服务端硬上限,已钳制为 200MB / 64MB


5. 与其它计数方式的对比

  • 不用 grep 的匹配数:grep -c / grep 输出的 Found N matches 是匹配行数,不是字数,也不区分汉字与 ASCII 字母,更没有码点 / 字素簇口径。想用 grep 统计"汉字数"只能靠 [一-龥] 这类范围匹配,既不可靠也随 locale 变化。

  • 不用 wc:wc -l / -m / -c 只给行数 / 字符数 / 字节数三件套;它给不出汉字数,也说不清"字符"是码点还是字素簇,更没有句数、段落数、脚本分类与 BOM 标记。

  • Intl.Segmenter 零依赖:Intl.Segmenter 已能给出字素簇、词边界与句边界;引入 nodejieba / @node-rs/jieba 之类会带来原生编译、二进制分发与平台差异问题,也会破坏"单文件 + 不联网 + 零构建"的目标。

  • 默认不给近似中文词数:ICU 对中文的切分是按词典规则做的近似,词数既不可靠又会随 ICU 版本漂移。默认关闭(CJK 下 words = 0),需要时显式传 wordsForCjk: true,并用 wordsApproximate = true 明确标注近似值,避免被当作事实引用。字符级指标才是稳定可比的。


6. 开发说明

本项目在 AI 协助下开发。 AI 参与了项目的设计取舍、实现与文档编写:统计口径的定义与边界条件、Unicode 口径的选择、大文件降级策略、白名单安全默认以及本文档,均由人与 AI 协作完成。全部代码与文档由人工逐条复核,并在本机真实环境(真实文件、真实 MCP stdio 握手、真实 Unicode 文本)下验证通过。

开发与测试:

npm install
npm test        # node --test test/

仓库内保留的是可复现的最小测试集:test/count.test.mjs,共 5 个用例,分别覆盖:中文样本的计数正确性、"返回体不含正文"契约、"未设置 TEXT_STATS_ROOTS 时拒绝一切路径"的安全默认、maxBytes 超过服务端硬上限时被钳制、以及符号链接/目录联接一律拒绝。开发期曾使用一套规模更大的临时测试(53 项)做交叉验证,该临时套件未随包发布;运行 npm test 即可复现当前保留的全部用例。


7. License

MIT —— 见 LICENSE。

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      Provides LIWC-style dictionary scoring of text with deterministic, provenance-first analysis, enabling researchers and AI agents to perform reproducible text analysis via MCP tools.
      Apache 2.0
    • A
      license
      A
      quality
      B
      maintenance
      Enables counting only the Chinese characters in a piece of text, ignoring punctuation, whitespace, Latin letters, digits, and emoji, while also returning a per-category breakdown and Chinese-to-total ratio. It can additionally batch-count up to 500 texts at once and extract just the Chinese characters from any given text, making it useful for copy length checks, homework word counts, and title limits.
      3
      MIT
    • A
      license
      B
      quality
      B
      maintenance
      Enables local, offline AI-text detection over MCP with read-only tools for status checking and statistical analysis of text using calibrated compact models.
      2
      BSD 3-Clause
    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables MCP clients to evaluate text or local files for LLM-output quality issues, returning 0-100 scores, grades, and precise line/column findings. It also lets clients list all available lint rules and severities.
      MIT