STE Dictionary MCP Server
An MCP server that checks text against ASD-STE100 Simple Technical English(STE): which words are approved, which aren't, and what STE word replaceseach violation. Works entirely offline from a static dictionary snapshot indata/ โ no network access at runtime. Seedocs/superpowers/specs/2026-08-21-ste-mcp-design.md for the full design.
Setup
pip install -r requirements.txt
python scripts/download_nltk_data.py
pytest
The check_structure tool needs two small NLTK data packages (thepunkt_tab sentence/word tokenizer and the averaged_perceptron_tagger_engPOS tagger -- classic statistical models, not deep learning). Runningpython scripts/download_nltk_data.py once after installing dependenciesdownloads them and trims out the non-English tokenizer languages NLTK'sdownloader pulls by default, keeping the on-disk footprint to a few MBinstead of ~58MB. It's safe to re-run. If you skip this step, check_structureraises a RuntimeError telling you to run it.
The server reads its dictionary snapshot from the STE_DATA_DIR environmentvariable, defaulting to ./data (relative to the working directory theserver is launched from). The snapshot in data/ is committed to this repo,so no separate download step is needed.
Running standalone
python -m ste_mcp.server
Speaks MCP over stdio.
Installing into Claude Code
Register the server with the Claude Code CLI. Use an absolute path to yourPython interpreter if python on your PATH doesn't have the mcp packageinstalled.
Local scope (available only when Claude Code is run from this repo):
cd /absolute/path/to/ste-dictionary-mcp
claude mcp add --transport stdio --env STE_DATA_DIR=/absolute/path/to/ste-dictionary-mcp/data ste-dictionary -- python -m ste_mcp.server
User scope (available from any directory). Because user-scope serversdon't run with this repo as their working directory, wrap the launch in asmall script that cds into the repo first, e.g. ~/.claude/ste-launcher.sh:
#!/bin/sh
cd /absolute/path/to/ste-dictionary-mcp
exec python -m ste_mcp.server
Then register it:
chmod +x ~/.claude/ste-launcher.sh
claude mcp add --transport stdio --scope user --env STE_DATA_DIR=/absolute/path/to/ste-dictionary-mcp/data ste-dictionary -- ~/.claude/ste-launcher.sh
Verify with claude mcp list, or /mcp inside a session.
Claude Desktop configuration
Add to claude_desktop_config.json:
{
"mcpServers": {
"ste-dictionary": {
"command": "python",
"args": ["-m", "ste_mcp.server"],
"cwd": "/absolute/path/to/ste-dictionary-mcp",
"env": {
"STE_DATA_DIR": "/absolute/path/to/ste-dictionary-mcp/data"
}
}
}
}
Tools
| Tool | Purpose |
|---|---|
check_word(word) |
Is this word/phrase STE, and what replaces it? |
check_text(text, include_unknown=True) |
Scan a document for non-STE, ambiguous, unknown, and technical words with positions. |
check_structure(text) |
Scan a document for structural STE violations: overlong sentences, passive voice, non-imperative mood, noun clusters of 4+, overlong paragraphs, gerund-as-noun. |
lookup_technical_term(term) |
Look up an approved technical term or abbreviation. |
dictionary_info() |
Dictionary source, freshness, and coverage stats. |
check_word/check_text are word-list-based, not a grammar checker: theycheck vocabulary, not sentence structure. check_structure adds lightweightstructural checks (via a small statistical POS tagger, not a full grammarengine) for the ASD-STE100 rules a word list can't catch -- see itsdocstring in ste_mcp/structure.py for the exact rules and their heuristiclimitations. It is diagnostic only (no rewrite suggestions); the agent usingthese tools is responsible for rewriting.
Some words have both an STE-approved sense and a non-STE sense (e.g. "long"as a plain adjective is STE, but "as long as"/"no longer" is not). For those,check_word returns status: "ambiguous" (instead of "non_ste") alongwith a note telling the caller to verify which sense applies in context,and check_text reports them in a separate ambiguous bucket/summary countrather than non_ste. status: "non_ste" is reserved for words where everymatched sense is non-STE.