chinese-nlp-mcp
中文 NLP 能力的 MCP Server,面向海外开发者。本地 stdio 运行,纯离线推理。
特性
- stdio transport — 本地进程通信,不开放任何端口
- 纯本地 — 关闭 fastmcp 版本检查,启动零网络请求
- 协议安全 — 日志一律写 stderr,绝不污染 stdout 的 JSON-RPC 流
环境要求
- Python 3.13+
- 依赖装在项目专用 venv,不污染系统 Python
安装
方式一:uvx 一键运行(推荐,无需安装)
uvx chinese-nlp-mcp
需要先安装 uv:https://docs.astral.sh/uv/getting-started/installation/
(macOS/Linux 用 curl -LsSf https://astral.sh/uv/install.sh | sh,
Windows 用 irm https://astral.sh/uv/install.ps1 | iex)
方式二:pip 安装
pip install chinese-nlp-mcp
# 安装后同样可用命令行启动
chinese-nlp-mcp
方式三:从源码安装(备选,开发用)
git clone https://github.com/leonmch-byte/chinese-nlp-mcp
cd chinese-nlp-mcp
# Windows (Git Bash)
python -m venv .venv
./.venv/Scripts/python.exe -m pip install -r requirements.txt
# macOS / Linux
python3 -m venv .venv
./.venv/bin/python -m pip install -r requirements.txt
客户端接入
推荐用 uvx,无需关心 Python 环境:
{
"mcpServers": {
"chinese-nlp-mcp": {
"command": "uvx",
"args": ["chinese-nlp-mcp"]
}
}
}
若用 pip 安装(方式二):
{
"mcpServers": {
"chinese-nlp-mcp": {
"command": "chinese-nlp-mcp"
}
}
}
若从源码安装(方式三):
{
"mcpServers": {
"chinese-nlp-mcp": {
"command": "/absolute/path/to/chinese-nlp-mcp/.venv/Scripts/python.exe",
"args": ["/absolute/path/to/chinese-nlp-mcp/server.py"]
}
}
}
工具
已实现工具
| 工具 | 签名 | 说明 |
|---|---|---|
hello_world |
() -> str |
健康检查,返回 Hello from Chinese NLP MCP |
segment_chinese |
(text: str, mode: str = "default") -> list[str] |
jieba 分词,mode 支持 default / search / index |
convert_pinyin |
(text: str, style: str = "tone", separator: str = " ") -> str |
pypinyin 拼音转换,style 支持 tone / tone2 / initials / first_letter |
extract_keywords |
(text: str, topN: int = 10) -> list[dict] |
TF-IDF 关键词提取,返回 [{word, weight}],按权重降序 |
detect_sensitive_words |
(text: str, words: list[str] | None = None) -> dict |
自定义敏感词检测,Aho-Corasick 自动机 |
🔴
detect_sensitive_words红线(不可协商)本工具不含任何内置词库,也不内置任何示例词。词库唯一来源是调用方传入的
words参数。传[]或None等同于不检测,直接返回{"matches": [], "clean": true}。 这是项目级设计红线:内容安全策略必须由使用者自己掌控,工具不得替他预设。重叠匹配策略:返回全部命中,不去重、不做最长/最短优先裁剪。 理由:调用方是自己词库的负责人,最清楚"命中什么"才是关心的信号。 若工具替他裁剪(例如只留最长匹配),他既无法知道被裁掉的短词也命中了, 也无法对重叠区间做差异化处置。拿到全部命中后,调用方完全可以按
index自行裁剪或聚合,而工具不做这个预设立场。例:
text="中华人民共和国",words=["中国人民","人民"]→ 返回 2 条命中,index分别为0和2。实现方案:pyahocorasick(实测 Windows + Python 3.13 有预编译 wheel, 无需本地编译;4813 词库 × 10 万字文本耗时 0.008 秒)。
index是字符索引(中文按 1 字计,非字节索引)。返回值读取方式:本工具返回
dict,fastmcp 会将其直接展开为structuredContent,不额外加result包装层(这与返回list/str的 工具不同,后者会被包成structuredContent.result)。 调用方应从structuredContent.matches与structuredContent.clean取值。
extract_keywords说明:
- 底层 jieba 的参数名是
topK(非topN),且需withWeight=True才会返回权重。weight是 TF-IDF 原始分,未归一化,值域通常 0 ~ 6,可大于 1.0 (例:"天安门广场" → 1.6316)。它表示该词在当前语料中的重要程度, 不是概率或百分比。- 返回顺序已按权重降序;
topN超过可提取词数时返回全部词,不报错。- 本工具是四个业务工具中唯一返回
list[dict]的,属有意设计。- 中英混合文本中,英文单词会被 jieba 作为独立 token 保留并参与 TF-IDF 计算, 不会被过滤(例:
Python 编程语言很强大→ 提取出Python,weight 3.98)。
style四种风格说明:实测 pypinyin 0.55.0 的lazy_pinyin(text, style="bad")不会报错,而是静默降级为Style.NORMAL(带调拼音)。因此本工具在入口处 强制白名单校验,不把非法style 透传给底层库。取值参考:
tone→zhōng、tone2→zho1ng、initials→zh、first_letter→z。
tone2标注规则:遵循 pypinyin 原生命名规则,声调数字标注在元音后 (如zho1ng),而非词尾(zhong1)。这是 pypinyin 的既有行为,非缺陷。
mode三模式说明:jieba 0.42.1 顶层没有cut_for_index, 且tokenize(mode=...)内部只区分default与"其他",传index会 静默降级为 search。本项目显式将index映射到cut_for_search, 行为与search一致,避免给调用方"index 是独立模式"的错觉。
search/index下jieba 内部计算的(word, start, end)位置信息不返回, 返回值统一为list[str]。
错误处理:参数非法抛
ValueError,内部失败抛RuntimeError, 均由 fastmcp 转成isError=true,工具签名保持纯净、不返回错误包装体。
测试规约(Day 3 锁定):
- 反例必须同时断言
isError=true且 错误文案包含预期片段。只看标志位会漏过 "底层库静默降级"类回归——错误可能被包装成别的异常,isError照样为true。- stdio 子进程的
stderr必须接文件或DEVNULL,绝不接subprocess.PIPE。 fastmcp 报错时 rich 会打印几十 KB traceback,塞满管道会导致 server 侧写阻塞、 响应永远发不出(表现为假死/超时,而非真实崩溃)。- 提交前必须用
git status检查暂存区,确认不含本地临时文件; 禁止git add -A后直接 commit。本地取证脚本、stderr 日志等 必须先确认已被.gitignore覆盖。
detect_sensitive_words刻意不内置任何词库。仅接受调用方传入的words, 返回{matches: [{word, index}], clean: bool}。
开发
验收统一走 Inspector 手工验证:
npx @modelcontextprotocol/inspector \
./.venv/Scripts/python.exe server.py
浏览器打开提示的地址(默认 http://localhost:6274),在 Tools 面板即可看到并调用工具。
Day 2 状态
| 工具 | 状态 | 说明 |
|---|---|---|
segment_chinese |
✅ 已实现 | jieba 三模式(default / search / index),mode 白名单校验 |
路线图
- Day 1 — 项目骨架 +
hello_world+ Inspector 验收 - Day 2 —
segment_chinese(jieba 三模式) - Day 3 —
convert_pinyin(pypinyin 四 style) - Day 4 —
extract_keywords(TF-IDF) - Day 5 —
detect_sensitive_words(Aho-Corasick)
每个工具独立实现、独立验收、独立提交。
License
MIT
Metadata
Release files for chinese-nlp-mcp 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| chinese_nlp_mcp-0.1.0.tar.gz | 13.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| chinese_nlp_mcp-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 31.1 kB
Release files / chinese_nlp_mcp-0.1.0.tar.gz
| Download URL | chinese_nlp_mcp-0.1.0.tar.gz |
|---|---|
| Size | 13.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
30f3437d32cc385243f7c7bcd911d2caf8e3908e10b2ad6a17bddff7aed48621
|
|
BLAKE2b-256 checksum How to use checksums |
48165fe49eadf907809b72fe4ec5d4042669e1d51f0f4adede3d2e03d90f96e0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / chinese_nlp_mcp-0.1.0-py3-none-any.whl
| Download URL | chinese_nlp_mcp-0.1.0-py3-none-any.whl |
|---|---|
| Size | 18.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b832ea20bc05f5aa5866692931493a6e37f82d7cf50eb9c9844df3d6b4cd9935
|
|
BLAKE2b-256 checksum How to use checksums |
24d26fea5ad58ec604730ea69c8e68c8a4df24d1f80cc76c883aa550e17a700f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|