glossary-mcp
A small, general-purpose MCP server that lets an AI read, search, and safely edit a glossary file in the conlangkit glossary format — for any glossary, not tied to any one project.
The glossary is a Markdown pipe-table with four columns:
lemma | tags | definition | notes
----- | ---- | ---------- | -----
core | tier | the constitutive tier-1 material of a party | never shared
Writes go through conlangkit, which owns the file: it keeps entries sorted (by byte
order) and re-emits the glossary on save. On an already-sorted file that yields a
minimal diff — only the touched row moves. The file is re-read from disk before
each write (so a long-lived server picks up external hand-edits) and the write is
atomic (temp file + os.replace).
Prerequisites
- Python 3.11+
- uv
- A glossary directory or file, pointed to by
GLOSSARY_PATH
conlangkit (the glossary format library)
is a normal PyPI dependency, pulled in by uv sync.
MCP SDK compatibility
| glossary-mcp | mcp SDK |
|---|---|
0.2.0+ |
2.x |
0.1.1 |
1.x (pinned <2) |
0.1.0 |
broken — do not use |
0.1.0 declared only mcp>=1.0, so once mcp 2.0 was released a fresh resolve
pulled it in — and 2.0 removed mcp.server.fastmcp. The server then died at
import with ModuleNotFoundError, which a client sees only as a server offering
no tools at all (a crashed stdio server cannot report why). If you are pinned
to 0.1.0, upgrade — restarting will not help. 0.1.1 pinned mcp<2 as a
stopgap; 0.2.0 ports to the 2.x API proper.
Installation
uv sync # creates .venv, installs glossary-mcp (editable) + conlangkit + dev deps
Running tests
uv run pytest # runs the suite with branch coverage (gate: 100%)
The smoke tests run without GLOSSARY_PATH. Integration tests run against a
fixture glossary.
Running the server
export GLOSSARY_PATH=/path/to/glossary # a directory containing glossary.md …
export GLOSSARY_PATH=/path/to/glossary.md # … or a direct path to the file
uv run glossary-mcp
GLOSSARY_PATH may be a directory (the server looks for glossary.md inside
it) or a file. The server uses stdio transport. For a local checkout, set
command to a resolvable path, e.g. the project's
/path/to/glossary-mcp/.venv/bin/glossary-mcp:
{
"mcpServers": {
"glossary": {
"command": "glossary-mcp",
"env": {
"GLOSSARY_PATH": "/path/to/glossary"
}
}
}
}
For consuming the published package from another repo without a local
checkout or absolute paths, use uvx — see the next section.
Consuming from another repo (portable .mcp.json)
glossary-mcp is published to PyPI,
so any other repo can wire it into its MCP configuration with no local checkout,
no venv, and no absolute paths. uvx fetches and caches the package (and its
conlangkit / mcp dependencies) on demand:
{
"mcpServers": {
"glossary": {
"type": "stdio",
"command": "uvx",
"args": ["glossary-mcp==0.2.0"],
"env": {
"GLOSSARY_PATH": "${CLAUDE_PROJECT_DIR:-.}/../glossary"
}
}
}
}
command: "uvx",args: ["glossary-mcp"]— the console-script name equals the package name, so no--fromflag is needed.uvxresolves the package from PyPI into an ephemeral, cached environment on first launch.GLOSSARY_PATHis the only required environment variable. It may point at a directory (the server looks forglossary.mdinside) or directly at a file. The${CLAUDE_PROJECT_DIR:-.}/../glossaryvalue assumes the standard sibling layout where the consuming repo and itsglossaryrepo are checked out side by side.${CLAUDE_PROJECT_DIR}resolves the project root and requires Claude Code ≥ v2.1.195; the:-.fallback keeps it working (relative to the current directory) on older versions and other MCP clients.- Pin the version while pre-1.0. Because the tool surface may still change
before 1.0, pin so a new release can't reach every consuming repo at once and
break them in lockstep:
"args": ["glossary-mcp==0.2.0"]. Bump deliberately (repo by repo, or via your propagation tooling). Float the version (bare"glossary-mcp", always latest) only once the surface stabilizes at ≥ 1.0.
Tools
| Tool | Description |
|---|---|
lookup_term |
Exact lemma lookup → tags, definition, notes |
search_by_definition |
Find entries whose definition matches a query |
search_notes |
Free-text search over the notes column |
glossary_stats |
Entry count, tag histogram, unique-tag count |
list_terms |
All lemmas, optionally filtered by tag |
add_term |
Append a new entry (refuses a duplicate lemma) |
update_term |
Edit an existing entry's tags/definition/notes by lemma |
A note on slashes in definitions
In the conlangkit format, / separates alternative senses in the definition column.
A definition that contains a literal slash (e.g. allow/ask/deny) is stored
escaped on disk as allow\/ask\/deny — which renders as a plain / on GitHub
(CommonMark/GFM). You never type the escape: pass ordinary prose (with plain
slashes) to add_term/update_term, and read ordinary prose back — the server
escapes and unescapes transparently.
Case sensitivity
Lemma lookup, insertion, and sorting are case-sensitive (byte order) — conlangkit
targets writing systems where case-folding is not meaningful, so core and Core
are distinct entries. Use each term's canonical case: lowercase for ordinary terms,
uppercase for acronyms (AID, GCD). This keeps you from creating near-duplicates.
Methodology
Non-trivial work in this repo runs under the cc craft methodology
(~/code/me/cc); read constitution.md first. Follow strict TDD (see
AGENTS.md).
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file glossary_mcp-0.2.0.tar.gz.
File metadata
- Download URL: glossary_mcp-0.2.0.tar.gz
- Upload date:
- Size: 88.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.12.0 {"installer":{"name":"uv","version":"0.12.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
95905ed6a37e73c9d2636c18fd1ec7a90a2019f6f225620303d7e8bbd0ad7c83
|
|
| MD5 |
4c3a0e3f640aadfb44b3aafba146f843
|
|
| BLAKE2b-256 |
ad514f079ea37a22a20374ebba073eda8c04e772ccc6e6b3fff164b43865517e
|
File details
Details for the file glossary_mcp-0.2.0-py3-none-any.whl.
File metadata
- Download URL: glossary_mcp-0.2.0-py3-none-any.whl
- Upload date:
- Size: 14.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.12.0 {"installer":{"name":"uv","version":"0.12.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
959bb7f3b9e053499320166dadb8e033dc9ee46d8208e7da9d7f21b05b1ff2ef
|
|
| MD5 |
0256347c3d407c69b2d20ddb5e53818d
|
|
| BLAKE2b-256 |
b3dfdff5fdb6854705b1cf6598d9b37132e34b630b1bae4314c01c69f86121b8
|