{
  "markdown": "# biz.dfch.AsdSte100Mcp\n\n<!-- mcp-name: io.github.dfch/biz-dfch-asdste100mcp -->\n\n[![ASD-STE100: Issue 9](https://img.shields.io/badge/ASD--STE100-Issue%209-blue.svg)](https://www.asd-ste100.org/)\n[![License: AGPL v3](https://img.shields.io/badge/License-AGPLv3-blue.svg)](https://www.gnu.org/licenses/agpl-3.0)\n![Python](https://img.shields.io/badge/python-3.11%20%7C%203.12%20%7C%203.13-blue.svg)\n[![Lint and Test](https://github.com/dfch/biz.dfch.AsdSte100Mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/dfch/biz.dfch.AsdSte100Mcp/actions/workflows/ci.yml)\n[![TestPyPI version](https://img.shields.io/badge/dynamic/json?url=https://test.pypi.org/pypi/biz-dfch-asdste100mcp/json&label=TestPyPI&query=$.info.version&color=orange)](https://test.pypi.org/project/biz-dfch-asdste100mcp/)\n[![PyPI version](https://img.shields.io/badge/dynamic/json?url=https://www.pypi.org/pypi/biz-dfch-asdste100mcp/json&label=PyPI&query=$.info.version&color=blue)](https://www.pypi.org/project/biz-dfch-asdste100mcp/)\n[![PyPI downloads](https://img.shields.io/pypi/dm/biz-dfch-asdste100mcp.svg)](https://pypistats.org/packages/biz-dfch-asdste100mcp)\n[![MCP Registry](https://img.shields.io/badge/MCP_Registry-io.github.dfch%2Fbiz--dfch--asdste100mcp-8A2BE2.svg)](https://registry.modelcontextprotocol.io/?q=io.github.dfch/biz-dfch-asdste100mcp)\n[![Auth: none](https://img.shields.io/badge/auth-none-brightgreen.svg)](#authentication)\n\nAn MCP server for the [ASD-STE100 (Simplified Technical English) Issue 9 standard](https://www.asd-ste100.org/).\n\nASD-STE100: Copyright by (c) [ASD](https://www.asd-europe.org/).\n\nI am in no way affiliated with ASD. ASD does not endorse my work.\n\n## Table of Contents\n\n- [Tools](#tools)\n- [Resources](#resources)\n- [Installation](#installation)\n- [Usage](#usage)\n- [Authentication](#authentication)\n- [Add to OpenCode](#add-to-opencode)\n- [Development](#development)\n- [Related Projects](#related-projects)\n- [Make a Release](#make-a-release)\n- [License](#license)\n\n## Authentication\n\nThis server exposes only read-only lookup tools and resources over\nvocabulary and rules data that is bundled with the package; there is\nnothing to authenticate against. No API keys, tokens, or credentials are\nrequired or supported in either `stdio` or `sse` transport mode. If you\nexpose the `sse` transport beyond `localhost`, secure it at the network\nlayer (e.g. a reverse proxy) rather than expecting the server to\nauthenticate requests itself.\n\n## Tools\n\n### Vocabulary\n\n| Tool | Description |\n|---|---|\n| `word_find`  | Search for a term by exact name (case-insensitive) in the ASD-STE100 Issue 9 vocabulary. Return approved/rejected status, part of speech, STE examples, and approved alternatives. Use this first when you know the exact word. Use `word_match` with a wildcard if this tool returns no items. |\n| `word_find_many` | Search for multiple terms by exact name (case-insensitive) in a single call. Returns one `WordFindEntry` per input term (`term` + `results`), in the same order as the input, each holding 0, 1, or more matching vocabulary entries. |\n| `word_match` | Search the vocabulary using a regular expression pattern. Return all entries whose term matches. Use it to find all words with a common prefix or pattern (e.g. ^de or .*tion$). Paginated (`max_results`/`offset`); returns a `WordResult`. |\n| `word_fuzzy` | Search for a term with sequence-matching (Python difflib.get_close_matches). Results may not be obvious — use when `word_find` returns nothing and you want fuzzy suggestions. |\n| `word_list` | Return all vocabulary entries. Only use when you need to process the full vocabulary. Use `word_count` instead if you only need the total. Paginated (`max_results`/`offset`); returns a `WordResult`. |\n| `word_count` | Return the total number of entries in the vocabulary. Use instead of `word_list` when you only need the count. |\n| `word_synonym` | Search for vocabulary entries that are WordNet synonyms of a word, via the `biz-dfch-asdste100nlp` library's `Nlp` class. Use this to find approved alternatives for a non-STE word. |\n\n### Rules\n\n| Tool | Description |\n|---|---|\n| `rules_find` | Search for rules in the ruleset by exact id (case-insensitive), e.g. `R1.1` or `GR-8`. Use this first when you know the exact id. |\n| `rules_match` | Search rules using a regular expression matched against the rule `name` and `summary`. |\n| `rules_search` | Full-text search across every text a rule carries (section, category, name, summary, and all content blocks: text, notes, examples, technical noun/verb lists). Optionally restrict to specific content types. Paginated (`max_results`/`offset`); returns a `SearchResult`. |\n| `rules_by_section` | Search for rules by exact section name (case-insensitive), e.g. `Words`. |\n| `rules_by_category` | Search for rules by exact category name (case-insensitive), e.g. `Technical nouns`. |\n| `rules_examples` | Return content items across rules, optionally scoped by id/section/category and filtered by content type. Paginated (`max_results`/`offset`); returns a `RulesExamplesResult`. |\n| `rules_overview` | Return a lightweight, per-rule overview (id, type, section, category, name, optional summary, and content counts/flags) without shipping every content item. |\n| `rules_toc` | Return the distinct (section, category) pairs as a table-of-contents outline, optionally scoped to one section. |\n\n## Resources\n\nRead-only resources let a client browse or attach ruleset data directly (e.g. via\nan \"@mention\" or resource picker), without going through a tool call.\n\n| Resource URI | Description |\n|---|---|\n| `asdste100://rules/toc` | Table-of-contents outline of the ruleset: the distinct (section, category) pairs, each with the ids they contain. Mirrors the `rules_toc` tool with no `section` filter. |\n| `asdste100://rules/rule/{id_}` | A single rule/recommendation/information item by exact id (case-insensitive), e.g. `asdste100://rules/rule/R1.1`. Mirrors the `rules_find` tool; an unknown id resolves to an empty list rather than an error. |\n| `asdste100://version` | Installed version numbers of the MCP server itself and its three data-backing libraries: `biz-dfch-asdste100vocab`, `biz-dfch-asdste100rules`, and `biz-dfch-asdste100nlp`. |\n\n## Installation\n\n```bash\npip install biz-dfch-asdste100mcp\n```\n\nOr with [uv](https://docs.astral.sh/uv/):\n\n```bash\nuv add biz-dfch-asdste100mcp\n```\n\n## Usage\n\n### MCP Inspector\n\nIf you want to test the MCP server without a tool like `OpenCode`, you can do this with [`MCP Inspector`](https://modelcontextprotocol.io/docs/2026-07-28/tools/inspector).\n\n`MCP Inspector` is part of the `mcp[cli]` package. When you install this project with `--extra dev` you can use `MCP Inspector`.\n\nNOTE: The examples below use `bunx` instead of `npx` to launch `MCP Inspector`; `npx` has not been tested.\n\n### stdio (Claude Desktop, OpenCode, and other MCP hosts)\n\n```bash\nasdste100-mcp\n```\n\nRun `MCP Inspector` against the server over `stdio`:\n\n```bash\nbunx @modelcontextprotocol/inspector uv run --frozen --directory . asdste100-mcp\n```\n\n![MCP Inspector with `stdio`](./assets/mcp-stdio.png)\n\nNOTE: Sometimes, the MCP Inspector cannot connect to the MCP server via `stdio`. Use the `sse` option (see below) instead.\n\n### SSE / network\n\n```bash\nasdste100-mcp --transport sse --host localhost --port 8000\n```\n\nNOTE: You do not have to supply the option `--port` to the MCP server. The default value of `port` is `8000`.\n\nStart the server, then connect `MCP Inspector` to it — these are two separate commands, run in two separate terminals:\n\n```bash\n# terminal 1: start the server\nuvx --from . asdste100-mcp -t sse\n```\n\n```bash\n# terminal 2: launch the inspector and connect it to the running server\nbunx @modelcontextprotocol/inspector\n```\n\n![Start the MCP server with `uvx` and then start the `MCP Inspector` with `bunx`](./assets/uvx-mcp-bunx-inspector.png)\n\n![MCP Inspector with `sse`](./assets/mcp-sse.png)\n\n### Options\n\n| Option | Env var | Default | Description |\n|---|---|---|---|\n| `--transport` | `ASDSTE100_MCP_TRANSPORT` | `stdio` | Transport mode: `stdio` or `sse` |\n| `--host` | `ASDSTE100_MCP_HOST` | `localhost` | Bind address (SSE only) |\n| `--port` | `ASDSTE100_MCP_PORT` | `8000` | TCP port (SSE only) |\n| `--env` | — | auto-discovered | Path to a `.env` file |\n| `--file` / `-f` | `ASDSTE100_MCP_FILES` | _(empty)_ | Path to a vocabulary file (`*.jsonl`); repeatable |\n| `--rules-file` / `-r` | `ASDSTE100_MCP_RULES_FILES` | _(empty)_ | Path to a rules file (a single JSON array); repeatable |\n\n### Vocabulary configuration\n\n| Env var | Default | Description |\n|---|---|---|\n| `ASDSTE100_MCP_FILES` | _(empty)_ | Colon-separated paths to additional vocabulary files |\n| `ASDSTE100_MCP_USE_STE100` | `true` | Load the built-in ASD-STE100 Issue 9 vocabulary |\n| `ASDSTE100_MCP_USE_STE100_TECHNICAL_WORDS` | `false` | Also load the technical words vocabulary |\n\n### Rules configuration\n\n| Env var | Default | Description |\n|---|---|---|\n| `ASDSTE100_MCP_RULES_FILES` | _(empty)_ | Colon-separated paths to additional rules files (each a single JSON array) |\n| `ASDSTE100_MCP_USE_STE100_RULES` | `true` | Load the built-in ASD-STE100 Issue 9 ruleset |\n\n## Add to OpenCode\n\nTo add the ASD-STE100 (Simplified Technical English) MCP server to your OpenCode configuration:\n\n1. Open your OpenCode config file (typically `~/.config/opencode/opencode.json` or `~/.config/opencode/opencode.jsonc`)\n\n2. Add the following configuration to the `mcp` section (and use it via `stdio`):\n\n```json\n\"asdste100\": {\n  \"type\": \"local\",\n  \"enabled\": true,\n  \"command\": [\"uvx\", \"--from\", \"biz-dfch-asdste100mcp\", \"asdste100-mcp\"]\n}\n```\n\n3. Save the file and restart OpenCode\n\nThis enables OpenCode to access ASD-STE100 vocabulary and rules lookups for technical writing and documentation compliance.\n\n## Development\n\n### Install dev dependencies\n\n```bash\nuv sync --all-extras\n```\n\n### Run linters\n\n```bash\nuv run --frozen ruff format --check\nuv run --frozen ruff check\nuv run --frozen pylint $(git ls-files '*.py')\n```\n\n### Run tests\n\n```bash\nuv run --frozen python -m unittest discover -v -s tests -t . -p \"test_*.py\"\n```\n\n## Related Projects\n\nThis server is part of the ASD-STE100 tooling family:\n\n* [biz.dfch.AsdSte100Vocab](https://github.com/dfch/biz.dfch.AsdSte100Vocab) — the ASD-STE100 Issue 9 vocabulary library\n* [biz.dfch.AsdSte100Rules](https://github.com/dfch/biz.dfch.AsdSte100Rules) — the ASD-STE100 Issue 9 ruleset library\n* [biz.dfch.AsdSte100Nlp](https://github.com/dfch/biz.dfch.AsdSte100Nlp) — WordNet-based synonym lookup for ASD-STE100 words\n* [biz.dfch.AsdSte100Lookup](https://github.com/dfch/biz.dfch.AsdSte100Lookup) — an interactive CLI to look up words and rules\n* [biz.dfch.AsdSte100Mcp](https://github.com/dfch/biz.dfch.AsdSte100Mcp) — this repo: an MCP server exposing vocabulary and rules lookup tools\n\n## Make a Release\n\n### 1. Make sure all tests pass\n\nBefore releasing, make sure the CI pipeline is green on the `dev` branch:\n\n```bash\nuv run --frozen ruff format --check\nuv run --frozen ruff check\nuv run --frozen pylint $(git ls-files '*.py')\nuv run --frozen python -m unittest discover -v -s tests -t . -p \"test_*.py\"\n```\n\n### 2. Increase the version\n\nUpdate the version in `pyproject.toml`:\n\n```toml\nversion = \"x.y.z\"\n```\n\n### 3. Commit and push to `dev`\n\n```bash\ngit add pyproject.toml CHANGELOG.md\ngit commit -m \"chore: bump version to vx.y.z\"\ngit push origin dev\n```\n\n### 4. Merge `dev` into `main`\n\n```bash\ngit checkout main\ngit merge dev\ngit push origin main\n```\n\n### 5. Create and push a version tag\n\n```bash\nexport VERSION=x.y.z\ngit tag v${VERSION}\ngit push origin v${VERSION}\n```\n\nPushing the tag triggers the `publish.yml` workflow, which will:\n\n1. Build the sdist and wheel.\n2. Publish to **TestPyPI** (environment `testpypi`).\n3. Publish to **PyPI** (environment `pypi`), only if TestPyPI succeeded.\n4. Publish to the **MCP Registry** (`publish-to-mcp-registry` job) — requires the new version to be live on PyPI first.\n5. Create a **GitHub Release** with auto-generated notes and the distribution artifacts attached.\n\nThen switch back to `dev` to continue work:\n\n```bash\ngit checkout dev\n```\n\n### Configure Trusted Publishing\n\nThe workflow uses OIDC Trusted Publishing — no API tokens or secrets are needed.\n\n#### GitHub: create environments\n\nGo to your repo → **Settings** → **Environments** and create two environments:\n\n| Environment | Recommended protection |\n|---|---|\n| `testpypi` | None required |\n| `pypi` | Add a required reviewer to prevent accidental production releases |\n\n#### TestPyPI\n\nLog in at [test.pypi.org](https://test.pypi.org) → **Your account** → **Publishing** → **Add a new pending publisher**:\n\n| Field | Value |\n|---|---|\n| PyPI project name | `biz-dfch-asdste100mcp` |\n| Owner | `dfch` |\n| Repository | `biz.dfch.AsdSte100Mcp` |\n| Workflow name | `publish.yml` |\n| Environment | `testpypi` |\n\n#### PyPI\n\nLog in at [pypi.org](https://pypi.org) → **Your account** → **Publishing** → **Add a new pending publisher**:\n\n| Field | Value |\n|---|---|\n| PyPI project name | `biz-dfch-asdste100mcp` |\n| Owner | `dfch` |\n| Repository | `biz.dfch.AsdSte100Mcp` |\n| Workflow name | `publish.yml` |\n| Environment | `pypi` |\n\n### MCP Registry Publishing\n\nThe `publish-to-mcp-registry` job uses GitHub OIDC authentication and does not require additional setup — it will automatically publish to the [official MCP Registry](https://registry.modelcontextprotocol.io/) once the package is live on PyPI.\n\nVerify your server is registered:\n\n```bash\ncurl \"https://registry.modelcontextprotocol.io/v0.1/servers?search=io.github.dfch/biz-dfch-asdste100mcp\"\n```\n\n## License\n\n[AGPL-3.0-or-later](LICENSE)\n",
  "bytes": 13674,
  "sha": "fec172298d41170897ea523a01051abbb0f119eab37db032a58509ce009e1ce3",
  "repo_slug": "dfch/biz.dfch.asdste100mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_dfch_biz_dfch_asdste100mcp_cc54eb5b/readme"
}