About
An artifact manager for system specifications.
Security Report
Valid MCP server (2 strong, 1 medium validity signals). No known CVEs in dependencies. Package registry verified. Imported from the Official MCP Registry.
8 files analyzed · 1 issue found
Security scores are indicators to help you make informed decisions, not guarantees. Always review permissions before connecting any MCP server.
Permissions Required
This plugin requests these system permissions. Most are normal for its category.
What You'll Need
Set these up before or after installing:
Environment variable: SPECMGR_MCP_TRANSPORT
Environment variable: SPECMGR_MCP_HOST
Environment variable: SPECMGR_MCP_PORT
Environment variable: SPECMGR_ADR_DIR
How to Install
Add this to your MCP configuration file:
{
"mcpServers": {
"io-github-dfch-biz-dfch-specmgr": {
"env": {
"SPECMGR_ADR_DIR": "your-specmgr-adr-dir-here",
"SPECMGR_MCP_HOST": "your-specmgr-mcp-host-here",
"SPECMGR_MCP_PORT": "your-specmgr-mcp-port-here",
"SPECMGR_MCP_TRANSPORT": "your-specmgr-mcp-transport-here"
},
"args": [
"python",
"biz-dfch-specmgr"
],
"command": "uvx"
}
}
}Documentation
View on GitHubFrom the project's GitHub README.
biz.dfch.SpecMgr
An artifact manager for system specifications.
This project is an MCP server that you can use to manage different specification artifacts — see Concepts for the full list of artifact types and how they relate, and MCP Server / docs/MCP.md for the tool/resource/prompt reference.
The MCP server (and the management CLI) are optional. You install them as "extras" (see Installation).
Table of Contents
- Concepts
- Installation
- CLI Usage
- UC → PlantUML Diagrams
- Reference Graph Diagrams
- MCP Server
- Installing the specmgr Harness Files
- Usage
- Referencing Artifacts
- Multi-Language Artifacts
- Development
- Testing
- Make a Release
- License
Concepts
Every artifact is a plain markdown file with a YAML frontmatter block on disk — git-friendly, diffable, and readable/editable by hand. The filesystem is always the source of truth; the MCP server wraps it with structured, validated read/write/list/status tools (see Usage).
| Type | Purpose |
|---|---|
| QA — Question and Answer | Structured elicitation interview (organized by ISO/IEC 25010 characteristic) capturing stakeholder Q&A; usually where a new spec effort starts |
| GOL — Goal | High-level business goal — what the organization wants to achieve, above individual requirements |
| PRB — Problem Statement | Six-Sigma-style problem statement describing the problem a goal/requirement addresses |
| REQ — Requirement | A single system requirement (EARS-style phrasing), classified by ISO/IEC 25010 characteristic |
| UC — Use Case | Actor/system interaction describing a specific usage scenario |
| RSK — Risk | Risk-register entry: cause/trigger/consequence, 5x5 probability/impact assessment (initial + residual), TARA response strategy |
| DEC — Decision | General-purpose decision record (MADR-style), not limited to architecture |
| ADR — Architecture Decision Record | Architecture-specific decision record; deprecated, use DEC instead |
| TSK — Task List | Checklist of implementation tasks, e.g. for a requirement or feature |
| VCR — Verification Case Record | Verifies exactly one REQ or UC; holds a collection of AC-NNN acceptance criteria (each with a DTAIS verification method) plus one overall coverage outcome (full/partial/none) |
| SOP — Standard Operating Procedure | Step-by-step operational procedure with RASCI responsibility assignment and approval lifecycle |
| FEAT — Feature | Development work-unit plan/progress tracking (.specmgr/feat/<id>/README.md) |
| SYSRS — System Requirements Spec | Aggregates GOL/PRB/QA/UC/REQ/RSK/DEC-ADR/VCR via cross-reference lists into one navigable spec; its structure follows ISO/IEC/IEEE 29148:2018 (Systems and software engineering — Life cycle processes — Requirements engineering), with a few specmgr-only additions (e.g. ## Decisions, ## Risks) |
| TXT — Free-Form Text | Generic, minimally structured catch-all for unstructured markdown that does not warrant a dedicated domain (ad hoc notes, meeting minutes, review/audit write-ups, scratch analysis); free body (any markdown, incl. H2..H6) plus a mandatory newest-first ## Updates log |
A typical spec effort starts with a QA elicitation interview, which surfaces GOLs (goals) and PRBs (problems). Those inform REQs and UCs, which get risk-assessed (RSK) and backed by DECisions, verified via one VCR per REQ/UC (each collecting its acceptance criteria), and tracked via TSK task lists. A SYSRS ties all of it together into one ISO/IEC/IEEE 29148-structured specification. SOP and FEAT support the process itself rather than sitting in this chain, and TXT is the free-form catch-all that likewise sits outside it (any markdown that does not warrant a dedicated artifact type).
QA -> GOL / PRB -> REQ / UC -> RSK / DEC -> TSK, VCR -> SYSRS (aggregates all)
Installation
As a library only (no CLI, no MCP server):
pip install biz-dfch-specmgr
With the CLI:
pip install "biz-dfch-specmgr[cli]"
With the MCP server:
pip install "biz-dfch-specmgr[mcp]"
With semantic-similarity search (find_related/find_similar_text, see
Semantic Similarity Search below), add the
similarity extra on top of mcp:
pip install "biz-dfch-specmgr[mcp,similarity]"
Or with uv:
uv add "biz-dfch-specmgr[cli,mcp,similarity]"
CLI Usage
With the CLI you can generate schema and documentation. We use these commands
in pre-commit hooks and ci.yml.
No domain document-management commands (create/update/status/etc.) exist
in the CLI yet — those are currently MCP-only, see
MCP Server. The CLI covers version, mcp (below), a
handful of cross-cutting/doc-generation commands, and the diagram commands
— UC → PlantUML (see
UC → PlantUML Diagrams) and reference-graph (see
Reference Graph Diagrams) (specmgr --help
for the full list).
specmgr version
specmgr lint [paths]... [--type T [--dir D]] [--all] [--skip-unrecognized] # in-tree spec artifact parseability gate: full model-level parse of the paths (type inferred from the layout, --type overrides) or a --type/--all sweep (exit 0 parsed / 1 parse failure or missing mcp extra / 2 usage-or-resolution)
specmgr lint requires the mcp extra, like specmgr diagram (the
decoupling is tracked as issue #238).
UC → PlantUML Diagrams
Specmgr can turn UC artifacts into PlantUML diagrams — deterministic use-case and package diagrams, plus sequence diagrams attributed by the agent flow.
Sequence diagrams (agent path). The generate_uc_sequence_diagram MCP
prompt (in OpenCode: the self-triggering uc-diagram skill or the
/uc-diagram <id> command) runs the frozen rulebook flow: the agent
attributes every UNATTRIBUTED message (asking via the question tool when
not confident), validates with validate_plantuml, and writes
diagrams/uc/<id>.sequence.puml host-natively — no specmgr tool writes
.puml files.
Deterministic diagrams + tooling (CLI, deterministic-only — the CLI never
creates, overwrites, or diffs the agent-owned *.sequence.puml files):
specmgr diagram uc <id>|all --out <dir> [--check] # per-UC <id>.usecase.puml + package.puml; --check byte-diffs without writing (exit 0 ok / 1 diff / 2 usage-or-render error)
specmgr plantuml-check <path...> # validates any .puml through the chain (exit 0 valid / 1 invalid / 2 source misconfigured-or-unavailable / 3 inconclusive)
specmgr plantuml-encode <path|-> # offline classic SoWkI… encoding
Validation source. Exactly three env vars, the first one set is the
only source used (no fall-through, no PATH discovery, no public default):
SPECMGR_PLANTUML_JAR (a plantuml.jar path), SPECMGR_PLANTUML_BIN (an
executable speaking the PlantUML CLI contract), SPECMGR_PLANTUML_URL (a
PlantUML server base URL). All unset ⇒ offline structure-only validation.
Diagram content is never sent to plantuml.com unless you set that URL.
The normative rulebook ships as the specmgr://uc/plantuml resource; the
full MCP surface is in docs/MCP.md.
Reference Graph Diagrams
Specmgr can render the deterministic cross-reference network between its
artifacts (the <TYPE> <id> tag vocabulary behind the list_references
tool) as a PlantUML component diagram — one node per artifact (label = the
document title, truncated to the SPECMGR_DIAGRAM_MAX_TITLE limit, default
40), a stereotype + colour per artifact type (a frozen 15-entry palette),
nodes grouped into per-domain curly component "TYPE" { … } domain groups,
one label-free edge per unique reference ({src} --> {dst}), every edge
that lies on a cycle (self-loops and same-SCC ≥ 2) drawn with a red
label-free -[#red]-> arrow, and every reference
whose target cannot be resolved on disk drawn as a top-level <<UNRESOLVED>>
node. Fully deterministic: the same registry and the same arguments always
emit byte-identical source.
MCP tools. get_reference_diagram(type, id, depth=1, reverse=False, include_feat=True, title=None) renders one source document's reference
neighbourhood (the forward walk to depth, 1..5; reverse=True adds the
direct incoming references, additive and direct-only);
get_reference_diagram_all(include_feat=True, title=None) renders the
registry-wide graph. Both return the PlantUML source directly (no file
writes); the scoped tool accepts all 14 domains (adr included) and returns
the non-raising ParseFailureResult for an existing-but-broken source; the
registry-wide tool never raises for content.
CLI (writes the artifact, deterministic-only):
specmgr diagram refs <type> <id> [--depth N] [--reverse] [--no-feat] [--title T] [--out diagrams/refs] [--check] # scoped → <id>.refs.puml
specmgr diagram refs all [--no-feat] [--title T] [--out diagrams/refs] [--check] # registry-wide → reference-graph.puml
--no-feat drops every FEAT node except the explicitly requested source
(then every edge touching a dropped node). Exit codes: 0 written / no
diff, 1 a --check diff (a missing file counts as differing) or the
missing mcp extra, 2 a usage-or-resolution error (wrong-format
type/id/depth — a bare feat-NNN is rejected, use list_feat to
discover the exact id — a missing source, an existing-but-broken source,
all combined with a source). Written artifacts carry no structure-only
header (checker-clean by construction).
Validation. specmgr plantuml-check <path...> (or the validate_plantuml
MCP tool over the source) validates the diagram through the same strict
chain as the UC diagrams (the three SPECMGR_PLANTUML_* source env vars,
see UC → PlantUML Diagrams; all unset is the
offline structure-only floor).
Label limit. SPECMGR_DIAGRAM_MAX_TITLE (an int, default 40) bounds
the resolved-node H1 labels (word-boundary cut + …; a set-but-invalid
value falls back to 40); the @startuml diagram title is sanitized but
never truncated. Its set/valid/default/resolved status is reported by the
diagram section of the specmgr://config resource (the raw value is
never disclosed).
The normative rulebook ships as the specmgr://reference-graph resource;
the full MCP surface is in docs/MCP.md.
MCP Server
Requires the mcp extra. The server exposes resources, tools, and prompts
for document management, plus cross-cutting utilities (e.g. markdown
formatting).
The full, up-to-date list of every resource, resource template, tool, and
prompt — with parameters, MIME types, and descriptions — lives in
docs/MCP.md. That document generated from the live server
registration by specmgr mcp-docs and kept in sync by a pre-commit hook and
a CI check.
Environment Variables
Every document type stores its .md files in a base directory on disk —
the file is always the source of truth, re-read and re-parsed on every
tool call, so hand-editing a file between calls is safe.
- ADRs: base directory defaults to
docs/adr, configurable via theSPECMGR_ADR_DIRenvironment variable. This is ADR-specific and not shared with other document types. - Requirements (REQ) and future document types: share one root directory,
configurable via the
SPECMGR_DOCS_DIRenvironment variable (defaultdocs), with each type's own subdirectory appended automatically (e.g.docs/reqfor requirements). - Features (FEAT): base directory defaults to
.specmgr/feat, configurable via theSPECMGR_FEAT_DIRenvironment variable. This is FEAT-specific, like ADRs above, and not shared viaSPECMGR_DOCS_DIR. - PlantUML validation source (UC diagrams):
SPECMGR_PLANTUML_JAR(a plantuml.jar path),SPECMGR_PLANTUML_BIN(an executable speaking the PlantUML CLI contract), andSPECMGR_PLANTUML_URL(a PlantUML server base URL) — the first one set is the only source used (no fall-through, no PATH discovery, no public default); all unset is the offline structure-only floor. See UC → PlantUML Diagrams for the how-to. - Reference-graph diagram label limit:
SPECMGR_DIAGRAM_MAX_TITLE(an int, default40) — the maximum length of a resolved node's H1 label in theget_reference_diagram/get_reference_diagram_allPlantUML diagrams (word-boundary cut +…; the diagram title itself is never truncated). A set-but-invalid value (empty, non-int, or < 1) falls back to40. Its set/valid/default/resolved status is reported by thediagramsection of thespecmgr://configresource (the raw value is never disclosed).
The specmgr mcp command's own transport settings are likewise
environment-driven: SPECMGR_MCP_TRANSPORT selects the transport (default
stdio; the allowed values are stdio, sse, and streamable-http), and
SPECMGR_MCP_HOST (default localhost) and SPECMGR_MCP_PORT (default
8000) are the bind address and TCP port, used only in
sse/streamable-http mode. The command's --transport/--host/--port
flags take precedence over the variables — see Start the MCP
Server below for the options table.
The find_related/find_similar_text tools (semantic-similarity search,
requires the similarity extra) are turned off by setting the
SPECMGR_SIMILARITY_DISABLED environment variable (any value;
presence-based) — see Semantic Similarity Search
below for the full behavior (install, the non-blocking background warmup at
server startup, the model cache location, and the structured unavailable
result both tools return when the feature is disabled or the backend/model
fails to load).
The semantic-similarity feature's model cache directory is the
FASTEMBED_CACHE_PATH environment variable (the third-party fastembed
backend's own variable, not a SPECMGR_* one): an unset or empty value
falls back to <tempdir>/fastembed_cache (e.g. /tmp/fastembed_cache on
Linux). The resolved directory is reported by the similarity section of
the specmgr://config resource — see Semantic Similarity
Search below for the full behavior.
The feat domain's two background cache-warming phases (frontmatter and
full-parse, run by the same unified server-startup warmup thread as the
similarity warmup) are likewise turned off by setting the
SPECMGR_FEAT_WARMUP_DISABLED environment variable (any value;
presence-based) — see the background warmup paragraph of Semantic
Similarity Search below for the thread's
full behavior and both opt-out flags.
SPECMGR_TESTS_NO_DOTENV is a presence-based test/CI sentinel (no
default; never set outside test runs): set to any value to skip the
CLI's module-level default .env load entirely, so a test run sees no
local (gitignored) .env configuration whatever the developer's machine
has.
All of the base directories above are resolved relative to the MCP server
process's own current working directory unless overridden by their env var
(or, for the shared SPECMGR_DOCS_DIR root, unless the server was started
with --directory/uv run --directory targeting your project). If that
CWD is not what you expect — e.g. after adding specmgr to an MCP host
per Add to OpenCode below — read the specmgr://config
resource to see every domain's actually-resolved absolute base directory
and whether its env var is explicitly set, without needing shell access to
the server's host.
Semantic Similarity Search
The find_related and find_similar_text tools rank documents by
semantic similarity using local sentence embeddings (no API keys, no
network at inference time). find_related(type, id) finds the documents
most related to an existing document; find_similar_text(query) finds the
documents most similar to a free-form query — e.g. a draft you have not
saved yet, for pre-creation dedup/discovery. Both tools always appear in
the tool list, regardless of whether the feature is installed or enabled:
when it is unavailable, each call returns a structured
{available: false, reason, message} result instead of raising.
Install. The tools need the optional similarity extra on top of
mcp — the exact commands are in Installation
(pip install "biz-dfch-specmgr[mcp,similarity]" or
uv add "biz-dfch-specmgr[cli,mcp,similarity]"). The backend is
fastembed running BAAI/bge-small-en-v1.5 (CPU-only, ONNX Runtime,
384-dim).
Model download and cache. The model is downloaded once from the
Hugging Face Hub the first time it is loaded (network required at that
point only; after that, inference is fully offline). It is cached in
$FASTEMBED_CACHE_PATH if that environment variable is set, otherwise in
<tempdir>/fastembed_cache (e.g. /tmp/fastembed_cache on Linux).
Background warmup at server startup. Unless both
SPECMGR_FEAT_WARMUP_DISABLED and SPECMGR_SIMILARITY_DISABLED are set,
the server starts a single background daemon thread at startup that runs
three warmup phases, strictly in order: the feat frontmatter phase
(cheap: frontmatter plus H1 only), the feat full-parse phase (expensive:
the full feat corpus), and the similarity phase, which embeds the full
document corpus into the in-memory cache. Each phase is independently
gated by its own opt-out flag: SPECMGR_FEAT_WARMUP_DISABLED (any value;
presence-based) skips the two feat phases, and
SPECMGR_SIMILARITY_DISABLED (any value; presence-based) skips the
similarity phase, regardless of whether the similarity extra is
installed. With the extra missing, or with the model failing to load, the
similarity phase runs the availability probe inside itself and exits
immediately without cache writes (still never raising). The thread is
non-blocking — server startup never waits for it (the model load/download,
if needed, happens inside the thread, not on the startup path) — and a
mid-warmup failure is logged and swallowed, leaving the cache partially
warm. Its purpose is to keep the first tool call fast: against a cold
cache, list_feat scans and re-parses the whole feat corpus on the
request path, and the similarity tools embed the corpus on demand — both
can cost minutes of CPU.
Opt-out. Set SPECMGR_SIMILARITY_DISABLED (any value; presence-based)
to disable the feature without uninstalling the extra — e.g. to skip the
model download entirely, on a host where the model was never downloaded,
or to free the memory the model and cache use. Both tools stay registered
either way. Set SPECMGR_FEAT_WARMUP_DISABLED (any value; presence-based)
to skip the two feat cache-warming phases without any other effect —
e.g. on a host where list_feat/get_feat are rarely called. With both
opt-out flags set, no warmup thread is started at all.
Introspection. Read the specmgr://config resource for the feature's
static configuration — its similarity section reports whether the
similarity extra is installed, whether the opt-out flag is set, the
model name, and the resolved cache directory (static facts only; reading
the resource never loads the model or creates the cache directory), and
its feat_warmup_disabled field reports whether the feat warmup opt-out
flag is set — and the specmgr://version resource for the installed
fastembed version (null when the extra is not installed).
Start the MCP Server
Start the server with the mcp command:
specmgr mcp
By default it runs over stdio, for MCP hosts that launch it as a
subprocess (see Add to OpenCode below). It can also
run over SSE/network:
specmgr mcp --transport sse --host localhost --port 8000
Or over the spec-current streamable-http transport, which replaces the
legacy/deprecated sse transport for HTTP deployments:
specmgr mcp --transport streamable-http --host localhost --port 8000
| Option | Env var | Default | Description |
|---|---|---|---|
--transport / -t | SPECMGR_MCP_TRANSPORT | stdio | Transport mode: stdio, sse, or streamable-http |
--host / -h | SPECMGR_MCP_HOST | localhost | Bind address (SSE/streamable-http mode only) |
--port / -p | SPECMGR_MCP_PORT | 8000 | TCP port (SSE/streamable-http mode only) |
Add to OpenCode
To add the specmgr MCP server to your OpenCode configuration:
-
Open your OpenCode config file (typically
~/.config/opencode/opencode.jsonor~/.config/opencode/opencode.jsonc) -
Add a configuration to the
mcpsection (and use it viastdio).A bare
uvx --from biz-dfch-specmgr[mcp] specmgr mcpcommand with no--directoryand noSPECMGR_*_DIRenv vars is unsafe: the server resolves every base directory (docs,docs/adr,.specmgr/feat, ...) relative to its own process's current working directory, which an MCP host is free to launch from anywhere — not necessarily your project root. Pick one of the two options below instead of the plain form:Option A — pin the working directory with
--directory(a globaluv/uvxflag, so it must come before--from):"specmgr": { "type": "local", "enabled": true, "command": [ "uvx", "--directory", "<path-to-your-project>", "--from", "biz-dfch-specmgr[mcp]", "specmgr", "mcp" ] }To also enable the Semantic Similarity Search feature (
find_related/find_similar_text), change[mcp]to[mcp,similarity]in the--fromvalue above — see that section for install/runtime-activation details.Option B — set the directory env vars explicitly instead of (or in addition to)
--directory:"specmgr": { "type": "local", "enabled": true, "command": [ "uvx", "--from", "biz-dfch-specmgr[mcp]", "specmgr", "mcp" ], "environment": { "SPECMGR_DOCS_DIR": "<path-to-your-project>/docs", "SPECMGR_ADR_DIR": "<path-to-your-project>/docs/adr", "SPECMGR_FEAT_DIR": "<path-to-your-project>/.specmgr/feat" } }The same
[mcp]->[mcp,similarity]change in the--fromvalue applies here too, to enable Semantic Similarity Search.Either option (or both together) makes the resolved base directories independent of wherever the MCP host happens to launch the server from. Whichever you choose, you can confirm it worked by reading the
specmgr://configresource, which reports the actually-resolved absolute base directory for every domain and whether its env var is explicitly set.Option C — run from a local source checkout (development). Options A and B both use
uvx(uv tool run), which resolvesbiz-dfch-specmgr[...]as a named package from the configured index (PyPI by default) into an ephemeral tool environment — they always run the published release, never local/unreleased changes. To instead run the project at a specific directory on disk — using its ownpyproject.toml, lockfile, and source tree directly, including unreleased/dev-branch commits — useuv run --directory <path-to-your-checkout>(no--from, notuvx):"specmgr": { "type": "local", "enabled": true, "command": [ "uv", "run", "--directory", "<path-to-your-checkout>", "--extra", "mcp", "--extra", "similarity", "specmgr", "mcp" ] }This is the mechanism for contributors/developers pointing OpenCode at their own git checkout instead of the published package. Repeatable
--extraflags (or--all-extrasfor everything) control which optional dependencies get synced into that local run, independent of what's published on PyPI — drop--extra similarityif you don't need Semantic Similarity Search. -
Save the file and restart OpenCode
Installing the specmgr Harness Files
Beyond the MCP server itself, this repo ships its agent harness files —
every markdown file under .opencode/{agent,command,skill}/ (the
subagents, slash commands, and skills the commands above drive) — as a
single packaged bundle: the specmgr://harness-bundle MCP resource
(application/json), an instructions field carrying the complete
install protocol plus a files array with each file's path (relative
to .opencode/), sha256, and verbatim content. The bundle is
generated from the repo's own tree by the specmgr harness-bundle CLI
command and drift-guarded by a pre-commit hook and a CI check, so the
published bundle always matches the released .opencode/ files
exactly. The Add to OpenCode section above covers
the MCP server setup the harness files pair with — it is not repeated
here.
Agent-driven install (recommended). Ask your agent to install the
specmgr harness files: it reads specmgr://harness-bundle (discoverable
via the MCP host's resource listing) and follows the bundle's
instructions field — picking its harness config root via the harness's
own configuration skill (OpenCode: customize-opencode), writing every
file byte-exact (skipping sha256-identical ones, asking you via the
question tool before overwriting a differing one), re-verifying every
write, and reporting installed/skipped/updated/failed per file. The
install never reads, writes, or merges opencode.json.
What gets installed. Every .opencode/agent/*.md subagent,
.opencode/command/*.md slash command, and .opencode/skill/*/SKILL.md
skill of the published package — the bundle is all-inclusive on purpose,
since the commands' dependency closure (e.g. /implement-feature
driving phase-orchestrator → phase-implementer) needs the existing
agents too.
Manual / Claude Code path. Claude Code's structurally similar
.claude/agents/*.md and .claude/commands/*.md conventions (one
markdown file per agent/command, YAML frontmatter plus prose body) make
the bundle's files hand-portable: copy each file's frontmatter and body
into the matching .claude/ file, translating the permission model. The
two models do not map one-to-one — OpenCode carries per-pattern
bash/edit/read permission rules (last matching rule wins), while
Claude Code's frontmatter takes a coarse tool allow-list (tools:) — so
a hand-ported file is a simplified equivalent, not an automatic
translation:
# .claude/agents/ref-finder.md -- hand-ported from the bundle's
# agent/ref-finder.md: the description and the prose body are unchanged,
# and the OpenCode per-pattern permission rules (read/glob/grep/list
# allowed, edit/write/task/bash denied) collapse to a coarse read-only
# tool allow-list.
---
name: ref-finder
description: >-
Lists and resolves the artifacts a single specmgr document references --
its `<TYPE> <id>` cross-reference lines -- by calling the `list_references`
MCP tool and reporting each referenced artifact's `type`/`id`/`title`/`path`,
flagging any that could not be resolved on disk. Read-only -- never edits,
writes, or commits.
tools: Read, Grep, Glob, mcp__specmgr__list_references
---
<the file's prose body, unchanged>
OpenCode's skills (.opencode/skill/*/SKILL.md) have no Claude Code
counterpart with the same self-triggering semantics; keep them as plain
reference documents if you need their content.
Usage
Once connected, your AI assistant sees two kinds of tools per document
domain: per-domain tools (create_<d>, get_<d>, list_<d>,
parse_<d>, plus get_<d>_example/get_<d>_template), and generic
dispatch tools that take a type= parameter and behave the same way
across every domain: update (whole-body or line-range edits),
set_status, set_classification, delete, and validate (ADR is the
one exception, predating this pattern, with its own dedicated tools
instead). See docs/MCP.md for the full list.
The server also ships prompts (e.g. create_req, update_req,
implement_task) — guided, multi-turn interview flows that are the
intended way to author documents conversationally, rather than calling
tools one by one. Most MCP hosts surface these as slash commands or a
prompt picker.
Day to day, you don't need to know any tool names at all — just ask your connected AI assistant in plain language, e.g.:
- "Create a new goal for reducing customer onboarding time."
- "List all open risks and show me the high-severity ones."
- "Draft a task list for requirement
<id>."
To resolve the cross-references an artifact already carries, see Referencing Artifacts.
Referencing Artifacts
specmgr documents cross-reference each other via <TYPE> <uuid> lines
in the structured locations (VCR's ## Verifies, SYSRS's per-section
bullet lists, DEC's ## Related Artifacts) and — anywhere in free-form
prose — via any of the reference tags, including a FEAT tag carrying
a feature's own id (the full feat-NNN-slug or the bare feat-NNN
number; the structured locations above remain uuid-only). The
list_references MCP tool resolves those references: point your
assistant at any artifact (<type> <id>) and it lists every
cross-reference tag in the artifact's body, each resolved to the
referenced document's type, id, title (its H1), and on-disk path.
Results are paged like every list_* tool; references that do not
resolve on disk come back as rows carrying an error (not a failure),
and any other free-form or non-conforming text is ignored.
In opencode, the /refs <type> <id> slash command
(.opencode/command/refs.md) wraps the same tool: it delegates to the
read-only ref-finder subagent (.opencode/agent/ref-finder.md), which
calls list_references and reports the rows, flagging any NOT FOUND
references. /refs requires opencode — the tool itself is plain MCP,
callable directly from any MCP client.
Also in opencode, the project-local
specmgr-refs skill (.opencode/skill/specmgr-refs/SKILL.md) is the
agent-initiated surface: it loads itself when a task matches
reference-retrieval phrasings, routes single-document requests to the
list_references tool, the ref-finder subagent, or the /refs
command, and codifies the graph, batch, and reverse workflows that
/refs and ref-finder do not cover.
Multi-Language Artifacts
The same artifact can exist in several languages. English is the default
and keeps its location (docs/<type>/); every other language is a
docs/<type>/<language>/ subfolder (<language> is a lowercase
two-letter code such as de) that holds the variant under the exact
same file name as its English source, with the same id and the
identical frontmatter and body structure. The language lives in the
file's location only — there is no language frontmatter field. It
applies to the twelve domains req, uc, tsk, qa, prb, gol,
rsk, dec, sop, vcr, sysrs and txt.
feat and adr are always English, permanently: no feat or adr
tool, resource or prompt takes a language, and the generic tools reject a
non-default language for those two types (language="en", the default,
is accepted and behaves as before).
- Reading and writing.
get_<d>,list_<d>andcreate_<d>, and the genericupdate,edit,set_status,set_classificationanddeletetools take an optionallanguage(default"en"; leaving it out behaves exactly as before).list_<d>(language="de")lists only the German variants. A variant is created from an existing English document:create_<d>(content, language="de", id=<id of the EN source>).validatestays English-only. - Headings. A translated heading is mapped back to its canonical
English heading through a per-language table, so a variant is checked
against the exact same schema as the English document. The file keeps
its translation. Closed-vocabulary values (
status,classification, RSKStrategy/Probability/Impact, VCRCoverageandAC-NNN (Method),Option N:/Step N:tokens,[ ]/[x], cross-reference tags, SOP lifecycle values) are never translated, and neither is the PRBproblem_statementsentence. - Translating. The MCP prompt
translate_artifact(type,id,language, optionalsource_language) drives the translation; the resourcesspecmgr://i18nandspecmgr://i18n/headings/{language}document the rules and return a language's heading table. In opencode: thetranslate-artifactskill and/translate <type> <id> <language> [source_language]. No tool translates by itself — the model does the translating around the deterministic tools. - Status and drift.
list_languages(type, id)reports the languages an artifact exists in.check_translation_drift(type, id, language)reports structural drift (missing, extra or reordered sections) and staleness (the English source is newer than the translation). In opencode: thetranslation-statusskill and/translation-status <type> <id> [language]. - English-only search and references.
find_related,find_similar_text,list_referencesandget_reference_diagram(_all)never see a language variant: a hit or a resolved reference is always the English document. - Adding a language. Add one file,
src/biz/dfch/specmgr/general/data/headings/<language>.json— a flat JSON object{"<translated heading>": "<canonical English heading>"}that covers exactly the fixed-text headings of the document models, with distinct values. No code change is needed. The drift testtests/general/models/test_heading_table_drift.pychecks every shipped table and names each missing or surplus heading. Without a table file a language code is rejected when a document of that language is read or written. - Titles and headings. Only the section headings (levels 2-6) are
mapped through the table. The document title (the level-1
#line) is free text in every language and is never looked up or rewritten, even when it equals a table entry (a German titleQuellestaysQuelle).
Development
Install dev dependencies
uv sync --all-extras
Install pre-commit hooks (one-time)
uv run --frozen pre-commit install
uv sync only installs Python dependencies into the venv — it never
registers the hooks from .pre-commit-config.yaml with git, so run
this once per clone before your first commit.
Run linters
uv run --frozen ruff format --check
uv run --frozen ruff check
uv run --frozen pylint $(git ls-files '*.py')
Run tests
uv run --frozen pytest -n auto --cov=src --cov-report=
Testing
You can exercise the MCP server directly with the MCP Inspector, in either its CLI (scriptable) or TUI (interactive terminal) client.
Prerequisites
- The
mcpextra installed (see Installation), so.venv/bin/specmgrexists. npx(ships with Node.js, version 22.19.0 or newer) — no separate Inspector install is required, it runs on demand vianpx @modelcontextprotocol/inspector.
Point the Inspector at the venv's specmgr binary directly (rather than at
uv run specmgr mcp) so none of uv run's own flags (e.g. --frozen) are
mistaken for Inspector flags:
npx @modelcontextprotocol/inspector --tui .venv/bin/specmgr mcp
npx @modelcontextprotocol/inspector --cli .venv/bin/specmgr mcp --method tools/list
CLI examples
Each CLI invocation connects, runs one request, prints the result, and exits — useful for scripting or a quick smoke test.
Get the specmgr://version resource:
npx @modelcontextprotocol/inspector --cli .venv/bin/specmgr mcp \
--method resources/read --uri specmgr://version
List task lists via the list_tsk tool:
npx @modelcontextprotocol/inspector --cli .venv/bin/specmgr mcp \
--method tools/call --tool-name list_tsk
Get one task list via the get_tsk tool (replace <id> with a real task
list id from the list_tsk output above):
npx @modelcontextprotocol/inspector --cli .venv/bin/specmgr mcp \
--method tools/call --tool-name get_tsk --tool-arg id=<id>
Add --format json to any of the above to get machine-readable output,
e.g. piped into jq.
Connecting with the TUI
npx @modelcontextprotocol/inspector --tui .venv/bin/specmgr mcp
This launches the server as an ad-hoc stdio target and opens the terminal
UI with it preselected (unlike the CLI, the TUI has no --server <name>
flag — it lists whichever servers are available and you pick one, though
with a single ad-hoc target there is nothing else to pick). Press c to
connect, then use the tabs to explore:
t— Tools tab: browse and call tools (e.g.get_tsk) with a form-based input.r— Resources tab: browse and read resources (e.g.specmgr://version,specmgr://iso25010).m— Prompts tab: list and render prompts.p— Protocol tab: raw JSON-RPC request/response history, useful for debugging.o— Console tab:stderrfrom the connectedspecmgr mcpprocess (tracebacks land here).c/d— connect / disconnect;EscorCtrl+C— exit.
The TUI requires a real TTY (raw-mode support) and does not run in a headless CI job — use the CLI client there instead.
Make a Release
The normative release procedure is the SOP
Perform a release of biz.dfch.SpecMgr
(SOP 98537416). Where this section, the script, or the command ever
disagree with the SOP, the SOP wins.
Using the OpenCode command (recommended)
/release [X.Y.Z | patch | minor | major] [--dry-run]
Documentation truncated — see the full README on GitHub.
Reviews
No reviews yet
Be the first to review this server!
More Developer Tools MCP Servers
Rea
Freeby Morluto · Developer Tools
Reverse engineer anything from your terminal or agent with one CLI and MCP server.
Paperclip
Freeby Paperclipai · Developer Tools
Trending hip-hop artist momentum scores across four cultural dimensions.
Toleno
Freeby Toleno · Developer Tools
Toleno Network MCP Server — Manage your Toleno mining account with Claude AI using natural language.
MCP Marketplace
Freeby mcp-marketplace · Developer Tools
Search and install MCP servers from inside your AI client.
mcp-creator-python
Freeby mcp-marketplace · Developer Tools
Create, build, and publish Python MCP servers to PyPI — conversationally.
by Lharries · Communication
Read, search, and send WhatsApp messages through your AI assistant
