zhtw-mcp-linguistic-linter

v2026.09.25

Traditional Chinese (zh-TW) linguistic linter enforcing Taiwan Ministry of Education standards through MCP

GitHub
Install command
npx skhub add reason-machines/zhtw-mcp-linguistic-linter
Markdown
SKILL.md

zhtw-mcp-linguistic-linter

Skill by ara.so — MCP Skills collection.

A linguistic linter for Traditional Chinese (zh-TW) that enforces Taiwan Ministry of Education (MoE) standards on vocabulary, punctuation, and character shapes. It runs as an MCP server inside AI coding assistants and catches Mainland Chinese (zh-CN) regional drift before it reaches the user.

What It Does

zhtw-mcp enforces three official Taiwan standards:

  1. Punctuation: Taiwan-style 「」 corner brackets instead of "" curly quotes, full-width punctuation (, 。 :)
  2. Character shapes: MoE standard forms (裏→裡, 着→著)
  3. Vocabulary: Cross-strait normalization (軟件→軟體, 內存→記憶體, 默認→預設)

The tool includes 1100+ vocabulary rules and 15 casing rules. For ambiguous terms, it uses the AI assistant itself to help decide context.

Key Use Cases

  • Lint Traditional Chinese documentation
  • Auto-fix cross-strait terminology drift
  • Enforce Taiwan MoE standards in CI/CD
  • Review AI-generated Chinese text for regional correctness
  • Quality gates for zh-TW content

Installation

Pre-built Binaries

macOS / Linux:

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/sysprog21/zhtw-mcp/releases/latest/download/zhtw-mcp-installer.sh | sh

Windows (PowerShell):

powershell -ExecutionPolicy Bypass -c "irm https://github.com/sysprog21/zhtw-mcp/releases/latest/download/zhtw-mcp-installer.ps1 | iex"

Building from Source

Requires Rust 1.91+:

git clone https://github.com/sysprog21/zhtw-mcp.git
cd zhtw-mcp
make
# Binary at target/release/zhtw-mcp

Quick Install with Make

make install      # build, install to ~/.local/bin, register with detected MCP clients
make uninstall    # remove binary and MCP registrations
make status       # check installation state

MCP Client Registration

Claude Code:

claude mcp add zhtw-mcp -- /path/to/zhtw-mcp

Codex CLI:

codex mcp add zhtw -- /path/to/zhtw-mcp

OpenCode:

opencode mcp add zhtw-mcp /path/to/zhtw-mcp

Generic (.mcp.json in project root):

{
  "mcpServers": {
    "zhtw-mcp": {
      "command": "/home/user/.local/bin/zhtw-mcp",
      "args": []
    }
  }
}

CLI Usage

Basic Commands

# Lint a file
zhtw-mcp lint README.md

# Auto-fix in place
zhtw-mcp lint file.md --fix

# Preview fixes without modifying
zhtw-mcp lint file.md --fix --dry-run

# Show telemetry summary
zhtw-mcp lint file.md --telemetry

# Clear judgment cache
zhtw-mcp cache clear

Advanced CLI Options

# Use strict MoE profile
zhtw-mcp lint doc.md --profile strict

# Relaxed mode for UI strings
zhtw-mcp lint ui.md --relaxed

# Detect AI writing artifacts
zhtw-mcp lint article.md --detect-ai

# Specify content type
zhtw-mcp lint notes.txt --content-type markdown

# Set max errors for quality gate
zhtw-mcp lint doc.md --max-errors 5

# Convert Simplified to Traditional (S2T)
zhtw-mcp s2t input.md -o output.md

Configuration File

Create .zhtw.toml in your project root:

# Profile: "base" or "strict"
profile = "base"

# Flags
relaxed = false
detect_ai = false

# Fix mode: "lexical_safe" or "none"
fix_mode = "lexical_safe"

# Max errors for quality gate (0 = unlimited)
max_errors = 0

# Content type: "auto", "plain", "markdown"
content_type = "auto"

MCP Tool API

When running as an MCP server, the AI assistant calls the zhtw tool with JSON parameters.

Tool: zhtw

Parameters:

{
  text: string;              // Required: text to lint
  profile?: "base" | "strict";  // Default: "base"
  relaxed?: boolean;         // Default: false
  detect_ai?: boolean;       // Default: false
  fix_mode?: "lexical_safe" | "none";  // Default: "none"
  max_errors?: number;       // Default: 0 (unlimited)
  content_type?: "auto" | "plain" | "markdown";  // Default: "auto"
  include_telemetry?: boolean;  // Default: false
}

Response:

{
  accepted: boolean;         // Quality gate verdict
  issues: Array<{
    line: number;
    column: number;
    message: string;
    suggestion?: string;
    rule_type: string;
  }>;
  corrected_text?: string;   // Only if fix_mode != "none"
  telemetry?: {
    input_tokens: number;
    output_tokens?: number;
    cache_creation_tokens?: number;
    cache_read_tokens?: number;
    // ...
  };
}

Common Patterns

1. Basic Linting

User says: "Check this paragraph for mainland terms"

Assistant calls:

{
  "name": "zhtw",
  "arguments": {
    "text": "這個軟件的默認設置存儲在內存中。"
  }
}

Response:

{
  "accepted": false,
  "issues": [
    {
      "line": 1,
      "column": 3,
      "message": "Mainland term: '軟件' → '軟體'",
      "suggestion": "軟體",
      "rule_type": "vocabulary"
    },
    {
      "line": 1,
      "column": 6,
      "message": "Mainland term: '默認' → '預設'",
      "suggestion": "預設",
      "rule_type": "vocabulary"
    },
    {
      "line": 1,
      "column": 12,
      "message": "Mainland term: '內存' → '記憶體'",
      "suggestion": "記憶體",
      "rule_type": "vocabulary"
    }
  ]
}

2. Auto-fix Text

User says: "Fix the zh-TW issues in this document"

Assistant calls:

{
  "name": "zhtw",
  "arguments": {
    "text": "這是一個測試文件,包含錯誤的標點.",
    "fix_mode": "lexical_safe"
  }
}

Response:

{
  "accepted": true,
  "issues": [],
  "corrected_text": "這是一個測試文件,包含錯誤的標點。"
}

3. Strict MoE Enforcement

User says: "Check this with strict MoE rules"

Assistant calls:

{
  "name": "zhtw",
  "arguments": {
    "text": "這裏有一些内容需要檢查。",
    "profile": "strict"
  }
}

Response includes character variant issues:

{
  "accepted": false,
  "issues": [
    {
      "line": 1,
      "column": 2,
      "message": "Non-standard character variant: '裏' → '裡'",
      "suggestion": "裡",
      "rule_type": "variant"
    },
    {
      "line": 1,
      "column": 7,
      "message": "Simplified character: '内' → '內'",
      "suggestion": "內",
      "rule_type": "variant"
    }
  ]
}

4. UI String Linting (Relaxed Mode)

User says: "Lint this UI string, skip grammar"

Assistant calls:

{
  "name": "zhtw",
  "arguments": {
    "text": "設定範圍: 1-100",
    "relaxed": true
  }
}

Relaxed mode:

  • Disables colon/dunhao enforcement
  • Uses en-dash for ranges
  • Skips grammar checks

5. AI Writing Review

User says: "Review this for AI writing artifacts"

Assistant calls:

{
  "name": "zhtw",
  "arguments": {
    "text": "首先,我們需要注意的是,在這個過程中,重要的是要確保系統的安全性。",
    "detect_ai": true
  }
}

Detects:

  • Filler phrases (首先, 在這個過程中)
  • Semantic safety words (需要注意的是, 重要的是)
  • Excessive copula/passive voice
  • Density-based patterns

6. Markdown-Aware Linting

User says: "Lint this markdown, skip code blocks"

Assistant calls:

{
  "name": "zhtw",
  "arguments": {
    "text": "這是說明文件.\n\n```rust\nlet code = \"不檢查\";\n```\n\n更多內容,這裏。",
    "content_type": "markdown"
  }
}

Excludes from scanning:

  • Fenced code blocks
  • Inline code spans
  • HTML blocks
  • YAML frontmatter

7. Quality Gate with Error Threshold

User says: "Reject if more than 3 zh-TW errors"

Assistant calls:

{
  "name": "zhtw",
  "arguments": {
    "text": "文檔內容...",
    "max_errors": 3
  }
}

Response:

{
  "accepted": false,
  "issues": [
    // 4+ issues listed
  ]
}

8. Telemetry for Cost Tracking

User says: "Lint this and include telemetry"

Assistant calls:

{
  "name": "zhtw",
  "arguments": {
    "text": "長文檔內容...",
    "include_telemetry": true
  }
}

Response includes:

{
  "accepted": true,
  "issues": [],
  "telemetry": {
    "input_tokens": 1250,
    "output_tokens": 0,
    "cache_creation_tokens": 0,
    "cache_read_tokens": 0,
    "total_cost_usd": 0.000375
  }
}

MCP Resources

The server exposes two read-only resources for AI assistants:

zh-tw://style-guide/moe

Taiwan Ministry of Education style guide covering:

  • Punctuation rules
  • Character shape standards
  • Vocabulary preferences

zh-tw://dictionary/ambiguous

Cross-strait term disambiguation dictionary with context examples.

Access in prompt:

Please consult zh-tw://style-guide/moe before making suggestions.

Rule Types

The linter reports issues with these rule_type values:

TypeDescriptionExample
vocabularyCross-strait vocabulary軟件→軟體
punctuationPunctuation marks.→。
spacingCJK-Latin/digit spacingzh tw→zh-TW
variantCharacter variants (strict)裏→裡
casingProper noun casinggithub→GitHub
grammarGrammar issues台→臺 (in 臺灣)
politicalPolitically colored terms祖國, 內地
fillerAI filler phrases (detect_ai)首先, 總的來說
safetySemantic safety (detect_ai)需要注意的是

Profiles and Flags

Profiles (Mutually Exclusive)

base (default):

  • Cross-strait vocabulary
  • Punctuation
  • Casing
  • Grammar
  • Political terms

strict:

  • Everything in base
  • Character variants (裏→裡)
  • Full MoE enforcement

Flags (Orthogonal)

relaxed:

  • Disables colon/dunhao enforcement
  • Disables grammar checks
  • Uses en-dash for ranges
  • For UI strings, software menus

detect_ai:

  • Filler phrase detection
  • Semantic safety words
  • Copula/passive voice checks
  • Density-based pattern detection
  • For reviewing AI-generated content

Combinations:

  • base + relaxed → Lenient UI linting
  • strict + relaxed → Variant normalization, lenient punctuation
  • base + detect_ai → Standard linting + AI artifact detection
  • strict + detect_ai → Full MoE + AI artifact detection

CI/CD Integration

GitHub Actions

name: zh-TW Lint
on: [push, pull_request]
jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install zhtw-mcp
        run: |
          curl --proto '=https' --tlsv1.2 -LsSf \
            https://github.com/sysprog21/zhtw-mcp/releases/latest/download/zhtw-mcp-installer.sh | sh
          echo "$HOME/.cargo/bin" >> $GITHUB_PATH
      - name: Lint documentation
        run: |
          zhtw-mcp lint docs/**/*.md --max-errors 0

GitLab CI

zhtw-lint:
  image: rust:latest
  script:
    - curl --proto '=https' --tlsv1.2 -LsSf https://github.com/sysprog21/zhtw-mcp/releases/latest/download/zhtw-mcp-installer.sh | sh
    - export PATH="$HOME/.cargo/bin:$PATH"
    - zhtw-mcp lint docs/**/*.md --max-errors 0

Pre-commit Hook

Create .git/hooks/pre-commit:

#!/bin/bash
set -e

# Find all staged markdown files
FILES=$(git diff --cached --name-only --diff-filter=ACM | grep '\.md$' || true)

if [ -n "$FILES" ]; then
  echo "Linting zh-TW files..."
  zhtw-mcp lint $FILES --max-errors 0
fi

Make executable:

chmod +x .git/hooks/pre-commit

Simplified to Traditional Conversion

Convert Simplified Chinese (zh-CN) to Traditional (zh-TW):

# File conversion
zhtw-mcp s2t input.md -o output.md

# Stdin/stdout
echo "软件开发" | zhtw-mcp s2t

# With profile
zhtw-mcp s2t input.md -o output.md --profile strict

Rust API:

use zhtw_mcp::converter::Converter;

fn main() {
    let converter = Converter::new();
    let traditional = converter.convert("软件开发");
    println!("{}", traditional);  // "軟體開發"
}

Rust Library Usage

If you want to embed the linter in your own Rust project:

Add to Cargo.toml:

[dependencies]
zhtw-mcp = "0.1"

Basic usage:

use zhtw_mcp::{LintEngine, LintOptions, Profile};

fn main() {
    let engine = LintEngine::new();
    let options = LintOptions {
        profile: Profile::Base,
        relaxed: false,
        detect_ai: false,
        fix_mode: None,
        max_errors: 0,
        content_type: "auto".to_string(),
    };
    
    let text = "這個軟件的默認配置。";
    let result = engine.lint(text, &options);
    
    println!("Accepted: {}", result.accepted);
    for issue in result.issues {
        println!("{}:{} - {}", issue.line, issue.column, issue.message);
        if let Some(suggestion) = issue.suggestion {
            println!("  Suggestion: {}", suggestion);
        }
    }
}

Auto-fix:

use zhtw_mcp::{LintEngine, LintOptions, FixMode};

fn main() {
    let engine = LintEngine::new();
    let mut options = LintOptions::default();
    options.fix_mode = Some(FixMode::LexicalSafe);
    
    let text = "這是測試,包含錯誤.";
    let result = engine.lint(text, &options);
    
    if let Some(corrected) = result.corrected_text {
        println!("Fixed: {}", corrected);  // "這是測試,包含錯誤。"
    }
}

Troubleshooting

MCP Server Not Detected

Check registration:

claude mcp list
# or
codex mcp list

Re-register:

claude mcp remove zhtw-mcp
claude mcp add zhtw-mcp -- /path/to/zhtw-mcp

Check process:

ps aux | grep zhtw-mcp

False Positives

Override rules in config:

Create .zhtw.toml:

# Disable specific rule types
[overrides]
disable_rules = ["political", "grammar"]

# Allow specific terms
allow_terms = ["內地"]  # if discussing Hong Kong geography

Use relaxed mode for UI strings:

zhtw-mcp lint ui-strings.md --relaxed

Cache Issues

Clear judgment cache:

zhtw-mcp cache clear

Cache location:

  • Linux: ~/.cache/zhtw-mcp/
  • macOS: ~/Library/Caches/zhtw-mcp/
  • Windows: %LOCALAPPDATA%\zhtw-mcp\cache\

Performance Issues

Batch processing:

Instead of linting many small files individually, concatenate and lint in one pass:

cat docs/*.md | zhtw-mcp lint --content-type markdown

Disable AI detection if not needed:

AI detection uses LLM sampling for ambiguous terms. Disable for faster processing:

zhtw-mcp lint doc.md  # AI detection off by default

Ambiguous Term Conflicts

For terms that vary by domain context (並發/並行, 進程/行程), the linter consults the AI assistant. If decisions are inconsistent:

  1. Check cache: zhtw-mcp cache clear
  2. Provide more context in surrounding text
  3. Use explicit overrides in config

Best Practices

For Documentation

# Use strict profile for formal documentation
zhtw-mcp lint docs/*.md --profile strict --fix

# Quality gate in CI
zhtw-mcp lint docs/*.md --max-errors 0

For UI Strings

# Use relaxed mode
zhtw-mcp lint src/i18n/zh-TW.json --relaxed

# Preserve technical terms
echo 'allow_terms = ["API", "JSON"]' >> .zhtw.toml

For AI-Generated Content

# Enable AI detection
zhtw-mcp lint generated.md --detect-ai

# Combine with auto-fix
zhtw-mcp lint generated.md --detect-ai --fix

For Mixed Content (Code + Docs)

# Use markdown content type to skip code blocks
zhtw-mcp lint README.md --content-type markdown

Examples from Real Projects

Example 1: Linting a README

Input:

# 我的項目

這是一個開源軟件,默認使用內存存儲.

## 安裝

使用 npm 安裝:

\`\`\`bash
npm install my-package
\`\`\`

Command:

zhtw-mcp lint README.md --content-type markdown

Output:

README.md:3:9: Mainland term: '軟件' → '軟體' [vocabulary]
README.md:3:11: Half-width comma should be full-width: ',' → ',' [punctuation]
README.md:3:13: Mainland term: '默認' → '預設' [vocabulary]
README.md:3:18: Mainland term: '內存' → '記憶體' [vocabulary]
README.md:3:22: Half-width period should be full-width: '.' → '。' [punctuation]

Auto-fix:

zhtw-mcp lint README.md --content-type markdown --fix

Fixed output:

# 我的項目

這是一個開源軟體,預設使用記憶體存儲。

## 安裝

使用 npm 安裝:

\`\`\`bash
npm install my-package
\`\`\`

Example 2: CI Quality Gate

GitHub Actions workflow:

name: Documentation Quality
on:
  pull_request:
    paths:
      - 'docs/**/*.md'
      - 'README*.md'

jobs:
  lint-zh-tw:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Install zhtw-mcp
        run: |
          curl --proto '=https' --tlsv1.2 -LsSf \
            https://github.com/sysprog21/zhtw-mcp/releases/latest/download/zhtw-mcp-installer.sh | sh
          echo "$HOME/.cargo/bin" >> $GITHUB_PATH
      
      - name: Lint Traditional Chinese
        run: |
          set -e
          CHANGED_FILES=$(git diff --name-only origin/main...HEAD | grep '\.md$' || true)
          if [ -n "$CHANGED_FILES" ]; then
            zhtw-mcp lint $CHANGED_FILES --profile strict --max-errors 0
          fi

Example 3: MCP Assistant Workflow

User: "Review this article draft for Traditional Chinese quality"

Assistant:

I'll check the article for zh-TW compliance using strict MoE standards and AI writing detection.

Tool call:

{
  "name": "zhtw",
  "arguments": {
    "text": "<article content>",
    "profile": "strict",
    "detect_ai": true
  }
}

Assistant response:

Found 12 issues:

Vocabulary (8):
- Line 5: '軟件' → '軟體'
- Line 12: '默認' → '預設'
- Line 23: '內存' → '記憶體'
...

AI artifacts (4):
- Line 3: Filler phrase "首先" at start of sentence
- Line 15: Semantic safety phrase "需要注意的是"
- Line 28: Excessive passive voice (4 instances in paragraph)
...

Would you like me to apply auto-fixes?

User: "Yes, fix them"

Assistant calls:

{
  "name": "zhtw",
  "arguments": {
    "text": "<article content>",
    "profile": "strict",
    "detect_ai": true,
    "fix_mode": "lexical_safe"
  }
}

Assistant: "Applied all lexical fixes. Manual review needed for 4 AI artifact issues (filler phrases require context to remove)."

Additional Resources

  • Full CLI reference: See project docs/cli.md
  • MCP tool details: See project docs/mcp.md
  • Rule reference: See project docs/rules.md
  • Internals: See project docs/internals.md
  • Release workflow: See project docs/release.md

Summary

Use zhtw-mcp to:

  1. Lint Traditional Chinese text for cross-strait terminology drift
  2. Auto-fix punctuation, vocabulary, and spacing issues
  3. Enforce Taiwan Ministry of Education standards
  4. Detect AI writing artifacts in generated content
  5. Integrate with CI/CD pipelines for quality gates
  6. Convert Simplified Chinese to Traditional

The tool runs as both a CLI and MCP server, making it accessible from command line, scripts, and AI coding assistants.

Discovery
Tags

No tags published for this skill.

Version
Latest version metadata

Version

v2026.09.25

Published

Sep 25, 2026

Category

Uncategorized

License

NOASSERTION

Source path

skills/zhtw-mcp-linguistic-linter

Default branch

main

Latest commit

329e67c

Tree SHA

01fd22f