Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
SPECMGR_ADR_DIRNoThe base directory where ADR .md files livedocs/adr
SPECMGR_MCP_HOSTNoBind address (SSE mode only)localhost
SPECMGR_MCP_PORTNoTCP port (SSE mode only)8000
SPECMGR_MCP_TRANSPORTNoTransport mode: stdio or ssestdio

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": false
}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}
experimental
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
create_tskA

Create a new task list: assigns a fresh id, derives a filename from the body's H1 title, validates the submitted body-only content, and writes the new document to the task list base directory. A content-validation failure of the submitted body returns a non-raising ValidateResult (valid=False, a single errors[].message capped at 300 chars as the generic validate tool caps it, feat-110) instead of raising AssertionError/pydantic.ValidationError (ADR f14f125e-eaad-4f4f-a6fd-3c931bed726e, GitHub issue #204 -- case 5 of the ADR 519d1206 non-raising-structured-result workaround chain); nothing is written in that case. Returns the newly created document's frontmatter only (no body); use the corresponding get_tsk tool to fetch the full document afterward.

get_tskA

Read, parse, and return a full task list document (frontmatter and body) by its id. Pass raw=True to return the frontmatter-stripped body text verbatim instead. With raw=True, optional read-style offset/limit window the raw read: offset (1-based, default 1) is the first body line to return, limit (line count, default through end of body) how many; out-of-range values clamp (offset > N returns the empty string), and coordinates with raw=False raise ValueError. A document that exists but fails to parse returns a ParseFailureResult (error/path/id) instead of raising; its error text is byte-identical to the domain's own list tool's failed-row error for the same file (identical field path and cause, including the trailing pydantic documentation line; ADR 9080b37c-82b3-4f63-81f1-79641d0bf14c). An invalid id (path-injection attempt or wrong format) is also a ValueError, raised before any file access. With raw=True, an optional numbered=True prefixes every returned body line with its 1-based absolute body-line number in the "<n>: " form (plain decimal, no padding) -- under offset/limit windowing the numbers start at the clamped offset and never restart at 1, so a number seen in the output can be fed straight back into the generic update tool's offset. numbered is meaningful only with raw=True: combining it with raw=False raises ValueError (like offset/limit), and a numbered read of a document that fails to parse returns the ParseFailureResult described above, never numbered text. Numbered output must never be fed back verbatim into content for update or create_tsk -- strip the "<n>: " prefix from each line first (it is likewise never a valid edit old_str).

get_tsk_exampleA

Return a complete, valid sample task list document as raw markdown -- frontmatter and body -- exercising every section, for use as a learning example.

get_tsk_templateA

Return a TSK document template -- frontmatter and every body field present, populated with short placeholder ('blind text') content -- as raw markdown, for use as a starting point when drafting a new task list.

list_tskA

Ids, titles, statuses, and refs of task lists in the configured task list base directory, one page at a time, for context before addressing one by id. 'ref' is an opaque, extensionless identifier -- not a filename to read from disk -- for documents that have no assigned id; use it with the get_tsk tool instead. An optional glob pattern (e.g. 'dead*') filters the listing to the task lists whose id matches it, case-insensitively; glob=None (the default) lists everything, and an empty string matches nothing. max_results/offset control paging (default page size 25, capped at 100); out-of-range values are clamped, not errored.

parse_tskA

Parse a task list markdown file (YAML frontmatter + body) from disk into a structured :class:~biz.dfch.specmgr.tsk.models.v1.TskDocument. An existing file that fails to parse returns a non-raising ValidateResult (valid=False, a single errors[].message capped at 300 chars as the generic validate tool caps it, feat-110) instead of raising AssertionError/pydantic.ValidationError/yaml.YAMLError (ADR f14f125e-eaad-4f4f-a6fd-3c931bed726e, GitHub issue #204 -- case 5 of the ADR 519d1206 non-raising-structured-result workaround chain); a truly-absent or unreadable path still raises the OSError-family file-access error (FileNotFoundError/PermissionError/OSError) from Path.read_text().

create_golA

Create a new goal: assigns a fresh id, derives a filename from the body's H1 title, validates the submitted body-only content, and writes the new document to the goal base directory. A content-validation failure of the submitted body returns a non-raising ValidateResult (valid=False, a single errors[].message capped at 300 chars as the generic validate tool caps it, feat-110) instead of raising AssertionError/pydantic.ValidationError (ADR f14f125e-eaad-4f4f-a6fd-3c931bed726e, GitHub issue #204 -- case 5 of the ADR 519d1206 non-raising-structured-result workaround chain); nothing is written in that case. Returns the newly created document's frontmatter only (no body); use the corresponding get_gol tool to fetch the full document afterward.

get_golA

Read, parse, and return a full goal document (frontmatter and body) by its id. Pass raw=True to return the frontmatter-stripped body text verbatim instead. With raw=True, optional read-style offset/limit window the raw read: offset (1-based, default 1) is the first body line to return, limit (line count, default through end of body) how many; out-of-range values clamp (offset > N returns the empty string), and coordinates with raw=False raise ValueError. A document that exists but fails to parse returns a ParseFailureResult (error/path/id) instead of raising; its error text is byte-identical to the domain's own list tool's failed-row error for the same file (identical field path and cause, including the trailing pydantic documentation line; ADR 9080b37c-82b3-4f63-81f1-79641d0bf14c). An invalid id (path-injection attempt or wrong format) is also a ValueError, raised before any file access. With raw=True, an optional numbered=True prefixes every returned body line with its 1-based absolute body-line number in the "<n>: " form (plain decimal, no padding) -- under offset/limit windowing the numbers start at the clamped offset and never restart at 1, so a number seen in the output can be fed straight back into the generic update tool's offset. numbered is meaningful only with raw=True: combining it with raw=False raises ValueError (like offset/limit), and a numbered read of a document that fails to parse returns the ParseFailureResult described above, never numbered text. Numbered output must never be fed back verbatim into content for update or create_gol -- strip the "<n>: " prefix from each line first (it is likewise never a valid edit old_str).

get_gol_exampleA

Return a complete, valid sample goal document as raw markdown -- frontmatter and body -- exercising every section, for use as a learning example.

get_gol_templateA

Return a GOL document template -- frontmatter and every body field present, populated with short placeholder ('blind text') content -- as raw markdown, for use as a starting point when drafting a new goal.

list_golA

Ids, titles, statuses, and refs of goals in the configured goal base directory, one page at a time, for context before addressing one by id. 'ref' is an opaque, extensionless identifier -- not a filename to read from disk -- for documents that have no assigned id; use it with the get_gol tool instead. An optional glob pattern (e.g. 'dead*') filters the listing to the goals whose id matches it, case-insensitively; glob=None (the default) lists everything, and an empty string matches nothing. max_results/offset control paging (default page size 25, capped at 100); out-of-range values are clamped, not errored.

parse_golA

Parse a goal markdown file (YAML frontmatter + body) from disk into a structured :class:~biz.dfch.specmgr.gol.models.v1.GolDocument. An existing file that fails to parse returns a non-raising ValidateResult (valid=False, a single errors[].message capped at 300 chars as the generic validate tool caps it, feat-110) instead of raising AssertionError/pydantic.ValidationError/yaml.YAMLError (ADR f14f125e-eaad-4f4f-a6fd-3c931bed726e, GitHub issue #204 -- case 5 of the ADR 519d1206 non-raising-structured-result workaround chain); a truly-absent or unreadable path still raises the OSError-family file-access error (FileNotFoundError/PermissionError/OSError) from Path.read_text().

create_prbA

Create a new Problem Statement: assigns a fresh id, derives a filename from the body's H1 title, validates the submitted body-only content, and writes the new document to the problem statement base directory. A content-validation failure of the submitted body returns a non-raising ValidateResult (valid=False, a single errors[].message capped at 300 chars as the generic validate tool caps it, feat-110) instead of raising AssertionError/pydantic.ValidationError (ADR f14f125e-eaad-4f4f-a6fd-3c931bed726e, GitHub issue #204 -- case 5 of the ADR 519d1206 non-raising-structured-result workaround chain); nothing is written in that case. Returns the newly created document's frontmatter only (no body); use the corresponding get_prb tool to fetch the full document afterward.

get_prbA

Read, parse, and return a full problem statement document (frontmatter and body) by its id. Pass raw=True to return the frontmatter-stripped body text verbatim instead. With raw=True, optional read-style offset/limit window the raw read: offset (1-based, default 1) is the first body line to return, limit (line count, default through end of body) how many; out-of-range values clamp (offset > N returns the empty string), and coordinates with raw=False raise ValueError. A document that exists but fails to parse returns a ParseFailureResult (error/path/id) instead of raising; its error text is byte-identical to the domain's own list tool's failed-row error for the same file (identical field path and cause, including the trailing pydantic documentation line; ADR 9080b37c-82b3-4f63-81f1-79641d0bf14c). An invalid id (path-injection attempt or wrong format) is also a ValueError, raised before any file access. With raw=True, an optional numbered=True prefixes every returned body line with its 1-based absolute body-line number in the "<n>: " form (plain decimal, no padding) -- under offset/limit windowing the numbers start at the clamped offset and never restart at 1, so a number seen in the output can be fed straight back into the generic update tool's offset. numbered is meaningful only with raw=True: combining it with raw=False raises ValueError (like offset/limit), and a numbered read of a document that fails to parse returns the ParseFailureResult described above, never numbered text. Numbered output must never be fed back verbatim into content for update or create_prb -- strip the "<n>: " prefix from each line first (it is likewise never a valid edit old_str).

get_prb_exampleA

Return a complete, valid sample problem statement document as raw markdown -- frontmatter and body -- exercising every section, for use as a learning example.

get_prb_templateA

Return a PRB document template -- frontmatter and every body field present, populated with short placeholder ('blind text') content -- as raw markdown, for use as a starting point when drafting a new problem statement.

list_prbA

Ids, titles, statuses, and refs of problem statements in the configured problem statement base directory, one page at a time, for context before addressing one by id. 'ref' is an opaque, extensionless identifier -- not a filename to read from disk -- for documents that have no assigned id; use it with the get_prb tool instead. An optional glob pattern (e.g. 'dead*') filters the listing to the problem statements whose id matches it, case-insensitively; glob=None (the default) lists everything, and an empty string matches nothing. max_results/offset control paging (default page size 25, capped at 100); out-of-range values are clamped, not errored.

parse_prbA

Parse a problem statement markdown file (YAML frontmatter + body) from disk into a structured :class:~biz.dfch.specmgr.prb.models.v1.PrbDocument. An existing file that fails to parse returns a non-raising ValidateResult (valid=False, a single errors[].message capped at 300 chars as the generic validate tool caps it, feat-110) instead of raising AssertionError/pydantic.ValidationError/yaml.YAMLError (ADR f14f125e-eaad-4f4f-a6fd-3c931bed726e, GitHub issue #204 -- case 5 of the ADR 519d1206 non-raising-structured-result workaround chain); a truly-absent or unreadable path still raises the OSError-family file-access error (FileNotFoundError/PermissionError/OSError) from Path.read_text().

create_qaA

Create a new Question and Answer (QA) document: assigns a fresh id, derives a filename from the body's H1 title, validates the submitted body-only content, and writes the new document to the QA base directory. A content-validation failure of the submitted body returns a non-raising ValidateResult (valid=False, a single errors[].message capped at 300 chars as the generic validate tool caps it, feat-110) instead of raising AssertionError/pydantic.ValidationError (ADR f14f125e-eaad-4f4f-a6fd-3c931bed726e, GitHub issue #204 -- case 5 of the ADR 519d1206 non-raising-structured-result workaround chain); nothing is written in that case. Returns the newly created document's frontmatter only (no body); use the corresponding get_qa tool to fetch the full document afterward.

get_qaA

Read, parse, and return a full QA document (frontmatter and body) by its id. Pass raw=True to return the frontmatter-stripped body text verbatim instead. With raw=True, optional read-style offset/limit window the raw read: offset (1-based, default 1) is the first body line to return, limit (line count, default through end of body) how many; out-of-range values clamp (offset > N returns the empty string), and coordinates with raw=False raise ValueError. A document that exists but fails to parse returns a ParseFailureResult (error/path/id) instead of raising; its error text is byte-identical to the domain's own list tool's failed-row error for the same file (identical field path and cause, including the trailing pydantic documentation line; ADR 9080b37c-82b3-4f63-81f1-79641d0bf14c). An invalid id (path-injection attempt or wrong format) is also a ValueError, raised before any file access. With raw=True, an optional numbered=True prefixes every returned body line with its 1-based absolute body-line number in the "<n>: " form (plain decimal, no padding) -- under offset/limit windowing the numbers start at the clamped offset and never restart at 1, so a number seen in the output can be fed straight back into the generic update tool's offset. numbered is meaningful only with raw=True: combining it with raw=False raises ValueError (like offset/limit), and a numbered read of a document that fails to parse returns the ParseFailureResult described above, never numbered text. Numbered output must never be fed back verbatim into content for update or create_qa -- strip the "<n>: " prefix from each line first (it is likewise never a valid edit old_str).

get_qa_exampleA

Return a complete, valid sample QA document as raw markdown -- frontmatter and body -- exercising every section, for use as a learning example.

get_qa_templateA

Return a QA document template -- frontmatter and every body field present, populated with short placeholder ('blind text') content -- as raw markdown, for use as a starting point when drafting a new QA document.

list_qaA

Ids, titles, statuses, and refs of QA documents in the configured QA base directory, one page at a time, for context before addressing one by id. 'ref' is an opaque, extensionless identifier -- not a filename to read from disk -- for documents that have no assigned id; use it with the get_qa tool instead. An optional glob pattern (e.g. 'dead*') filters the listing to the QA documents whose id matches it, case-insensitively; glob=None (the default) lists everything, and an empty string matches nothing. max_results/offset control paging (default page size 25, capped at 100); out-of-range values are clamped, not errored.

parse_qaA

Parse a QA document markdown file (YAML frontmatter + body) from disk into a structured :class:~biz.dfch.specmgr.qa.models.v2.QaDocument. An existing file that fails to parse returns a non-raising ValidateResult (valid=False, a single errors[].message capped at 300 chars as the generic validate tool caps it, feat-110) instead of raising AssertionError/pydantic.ValidationError/yaml.YAMLError (ADR f14f125e-eaad-4f4f-a6fd-3c931bed726e, GitHub issue #204 -- case 5 of the ADR 519d1206 non-raising-structured-result workaround chain); a truly-absent or unreadable path still raises the OSError-family file-access error (FileNotFoundError/PermissionError/OSError) from Path.read_text().

create_reqA

Create a new requirement: assigns a fresh id, derives a filename from the body's H1 title, validates the submitted body-only content, and writes the new document to the requirement base directory. A content-validation failure of the submitted body returns a non-raising ValidateResult (valid=False, a single errors[].message capped at 300 chars as the generic validate tool caps it, feat-110) instead of raising AssertionError/pydantic.ValidationError (ADR f14f125e-eaad-4f4f-a6fd-3c931bed726e, GitHub issue #204 -- case 5 of the ADR 519d1206 non-raising-structured-result workaround chain); nothing is written in that case. Returns the newly created document's frontmatter only (no body); use the corresponding get_req tool to fetch the full document afterward.

get_reqA

Read, parse, and return a full requirement document (frontmatter and body) by its id. Pass raw=True to return the frontmatter-stripped body text verbatim instead. With raw=True, optional read-style offset/limit window the raw read: offset (1-based, default 1) is the first body line to return, limit (line count, default through end of body) how many; out-of-range values clamp (offset > N returns the empty string), and coordinates with raw=False raise ValueError. A document that exists but fails to parse returns a ParseFailureResult (error/path/id) instead of raising; its error text is byte-identical to the domain's own list tool's failed-row error for the same file (identical field path and cause, including the trailing pydantic documentation line; ADR 9080b37c-82b3-4f63-81f1-79641d0bf14c). An invalid id (path-injection attempt or wrong format) is also a ValueError, raised before any file access. With raw=True, an optional numbered=True prefixes every returned body line with its 1-based absolute body-line number in the "<n>: " form (plain decimal, no padding) -- under offset/limit windowing the numbers start at the clamped offset and never restart at 1, so a number seen in the output can be fed straight back into the generic update tool's offset. numbered is meaningful only with raw=True: combining it with raw=False raises ValueError (like offset/limit), and a numbered read of a document that fails to parse returns the ParseFailureResult described above, never numbered text. Numbered output must never be fed back verbatim into content for update or create_req -- strip the "<n>: " prefix from each line first (it is likewise never a valid edit old_str).

get_req_exampleA

Return a complete, valid sample requirement document as raw markdown -- frontmatter and body -- exercising every section, for use as a learning example.

get_req_templateA

Return a REQ document template -- frontmatter and every body field present, populated with short placeholder ('blind text') content -- as raw markdown, for use as a starting point when drafting a new requirement.

list_reqA

Ids, titles, statuses, and refs of requirements in the configured requirement base directory, one page at a time, for context before addressing one by id. 'ref' is an opaque, extensionless identifier -- not a filename to read from disk -- for documents that have no assigned id; use it with the get_req tool instead. An optional glob pattern (e.g. 'dead*') filters the listing to the requirements whose id matches it, case-insensitively; glob=None (the default) lists everything, and an empty string matches nothing. max_results/offset control paging (default page size 25, capped at 100); out-of-range values are clamped, not errored.

parse_reqB

Parse a requirement markdown file (YAML frontmatter + body) from disk into a structured :class:~biz.dfch.specmgr.req.models.v1.ReqDocument. An existing file that fails to parse returns a non-raising ValidateResult (valid=False, a single errors[].message capped at 300 chars as the generic validate tool caps it, feat-110) instead of raising AssertionError/pydantic.ValidationError/yaml.YAMLError (ADR f14f125e-eaad-4f4f-a6fd-3c931bed726e, GitHub issue #204 -- case 5 of the ADR 519d1206 non-raising-structured-result workaround chain); a truly-absent or unreadable path still raises the OSError-family file-access error (FileNotFoundError/PermissionError/OSError) from Path.read_text().

create_rskA

Create a new risk: assigns a fresh id, derives a filename from the body's H1 title, validates the submitted body-only content, and writes the new document to the risk base directory. A content-validation failure of the submitted body returns a non-raising ValidateResult (valid=False, a single errors[].message capped at 300 chars as the generic validate tool caps it, feat-110) instead of raising AssertionError/pydantic.ValidationError (ADR f14f125e-eaad-4f4f-a6fd-3c931bed726e, GitHub issue #204 -- case 5 of the ADR 519d1206 non-raising-structured-result workaround chain); nothing is written in that case. Returns the newly created document's frontmatter only (no body); use the corresponding get_rsk tool to fetch the full document afterward.

get_rskA

Read, parse, and return a full risk document (frontmatter and body) by its id. Pass raw=True to return the frontmatter-stripped body text verbatim instead. With raw=True, optional read-style offset/limit window the raw read: offset (1-based, default 1) is the first body line to return, limit (line count, default through end of body) how many; out-of-range values clamp (offset > N returns the empty string), and coordinates with raw=False raise ValueError. A document that exists but fails to parse returns a ParseFailureResult (error/path/id) instead of raising; its error text is byte-identical to the domain's own list tool's failed-row error for the same file (identical field path and cause, including the trailing pydantic documentation line; ADR 9080b37c-82b3-4f63-81f1-79641d0bf14c). An invalid id (path-injection attempt or wrong format) is also a ValueError, raised before any file access. With raw=True, an optional numbered=True prefixes every returned body line with its 1-based absolute body-line number in the "<n>: " form (plain decimal, no padding) -- under offset/limit windowing the numbers start at the clamped offset and never restart at 1, so a number seen in the output can be fed straight back into the generic update tool's offset. numbered is meaningful only with raw=True: combining it with raw=False raises ValueError (like offset/limit), and a numbered read of a document that fails to parse returns the ParseFailureResult described above, never numbered text. Numbered output must never be fed back verbatim into content for update or create_rsk -- strip the "<n>: " prefix from each line first (it is likewise never a valid edit old_str).

get_rsk_exampleA

Return a complete, valid sample risk document as raw markdown -- frontmatter and body -- exercising every section, for use as a learning example.

get_rsk_templateA

Return a risk document template -- frontmatter and every body field present, populated with short placeholder ('blind text') content -- as raw markdown, for use as a starting point when drafting a new risk.

list_rskA

Ids, titles, statuses, and refs of risks in the configured risk base directory, one page at a time, for context before addressing one by id. Each line also carries the initial/residual 5x5 zone levels, the TARA strategy word, the first ## Scope entry, and the residual-risk coordinates (residual_probability/residual_impact/residual_product). 'ref' is an opaque, extensionless identifier -- not a filename to read from disk -- for documents that have no assigned id; use it with the get_rsk tool instead. An optional glob pattern (e.g. 'dead*') filters the listing to the risks whose id matches it, case-insensitively; glob=None (the default) lists everything, and an empty string matches nothing. max_results/offset control paging (default page size 25, capped at 100); out-of-range values are clamped, not errored.

parse_rskB

Parse a risk markdown file (YAML frontmatter + body) from disk into a structured :class:~biz.dfch.specmgr.rsk.models.v1.RskDocument. An existing file that fails to parse returns a non-raising ValidateResult (valid=False, a single errors[].message capped at 300 chars as the generic validate tool caps it, feat-110) instead of raising AssertionError/pydantic.ValidationError/yaml.YAMLError (ADR f14f125e-eaad-4f4f-a6fd-3c931bed726e, GitHub issue #204 -- case 5 of the ADR 519d1206 non-raising-structured-result workaround chain); a truly-absent or unreadable path still raises the OSError-family file-access error (FileNotFoundError/PermissionError/OSError) from Path.read_text().

create_sopA

Create a new Standard Operating Procedure: assigns a fresh id, derives a filename from the body's H1 title, validates the submitted body-only content, and writes the new document to the SOP base directory. A content-validation failure of the submitted body returns a non-raising ValidateResult (valid=False, a single errors[].message capped at 300 chars as the generic validate tool caps it, feat-110) instead of raising AssertionError/pydantic.ValidationError (ADR f14f125e-eaad-4f4f-a6fd-3c931bed726e, GitHub issue #204 -- case 5 of the ADR 519d1206 non-raising-structured-result workaround chain); nothing is written in that case. Returns the newly created document's frontmatter only (no body); use the corresponding get_sop tool to fetch the full document afterward.

get_sopA

Read, parse, and return a full SOP document (frontmatter and body) by its id. Pass raw=True to return the frontmatter-stripped body text verbatim instead. With raw=True, optional read-style offset/limit window the raw read: offset (1-based, default 1) is the first body line to return, limit (line count, default through end of body) how many; out-of-range values clamp (offset > N returns the empty string), and coordinates with raw=False raise ValueError. A document that exists but fails to parse returns a ParseFailureResult (error/path/id) instead of raising; its error text is byte-identical to the domain's own list tool's failed-row error for the same file (identical field path and cause, including the trailing pydantic documentation line; ADR 9080b37c-82b3-4f63-81f1-79641d0bf14c). An invalid id (path-injection attempt or wrong format) is also a ValueError, raised before any file access. With raw=True, an optional numbered=True prefixes every returned body line with its 1-based absolute body-line number in the "<n>: " form (plain decimal, no padding) -- under offset/limit windowing the numbers start at the clamped offset and never restart at 1, so a number seen in the output can be fed straight back into the generic update tool's offset. numbered is meaningful only with raw=True: combining it with raw=False raises ValueError (like offset/limit), and a numbered read of a document that fails to parse returns the ParseFailureResult described above, never numbered text. Numbered output must never be fed back verbatim into content for update or create_sop -- strip the "<n>: " prefix from each line first (it is likewise never a valid edit old_str).

get_sop_exampleA

Return a complete, valid sample Standard Operating Procedure document as raw markdown -- frontmatter and body -- exercising every section, for use as a learning example.

get_sop_templateA

Return a SOP document template -- frontmatter and every body field present, populated with short placeholder ('blind text') content -- as raw markdown, for use as a starting point when drafting a new Standard Operating Procedure.

list_sopA

Ids, titles, statuses, and refs of Standard Operating Procedures in the configured SOP base directory, one page at a time, for context before addressing one by id. 'ref' is an opaque, extensionless identifier -- not a filename to read from disk -- for documents that have no assigned id; use it with the get_sop tool instead. An optional glob pattern (e.g. 'dead*') filters the listing to the Standard Operating Procedures whose id matches it, case-insensitively; glob=None (the default) lists everything, and an empty string matches nothing. max_results/offset control paging (default page size 25, capped at 100); out-of-range values are clamped, not errored.

parse_sopA

Parse a Standard Operating Procedure markdown file (YAML frontmatter + body) from disk into a structured :class:~biz.dfch.specmgr.sop.models.v1.SopDocument. An existing file that fails to parse returns a non-raising ValidateResult (valid=False, a single errors[].message capped at 300 chars as the generic validate tool caps it, feat-110) instead of raising AssertionError/pydantic.ValidationError/yaml.YAMLError (ADR f14f125e-eaad-4f4f-a6fd-3c931bed726e, GitHub issue #204 -- case 5 of the ADR 519d1206 non-raising-structured-result workaround chain); a truly-absent or unreadable path still raises the OSError-family file-access error (FileNotFoundError/PermissionError/OSError) from Path.read_text().

create_sysrsA

Create a new System Requirements Specification: assigns a fresh id, derives a filename from the body's H1 title, validates the submitted body-only content, and writes the new document to the System Requirements Specification base directory. A content-validation failure of the submitted body returns a non-raising ValidateResult (valid=False, a single errors[].message capped at 300 chars as the generic validate tool caps it, feat-110) instead of raising AssertionError/pydantic.ValidationError (ADR f14f125e-eaad-4f4f-a6fd-3c931bed726e, GitHub issue #204 -- case 5 of the ADR 519d1206 non-raising-structured-result workaround chain); nothing is written in that case. Returns the newly created document's frontmatter only (no body); use the corresponding get_sysrs tool to fetch the full document afterward.

get_sysrsA

Read, parse, and return a full System Requirements Specification document (frontmatter and body) by its id. Pass raw=True to return the frontmatter-stripped body text verbatim instead. With raw=True, optional read-style offset/limit window the raw read: offset (1-based, default 1) is the first body line to return, limit (line count, default through end of body) how many; out-of-range values clamp (offset > N returns the empty string), and coordinates with raw=False raise ValueError. A document that exists but fails to parse returns a ParseFailureResult (error/path/id) instead of raising; its error text is byte-identical to the domain's own list tool's failed-row error for the same file (identical field path and cause, including the trailing pydantic documentation line; ADR 9080b37c-82b3-4f63-81f1-79641d0bf14c). An invalid id (path-injection attempt or wrong format) is also a ValueError, raised before any file access. With raw=True, an optional numbered=True prefixes every returned body line with its 1-based absolute body-line number in the "<n>: " form (plain decimal, no padding) -- under offset/limit windowing the numbers start at the clamped offset and never restart at 1, so a number seen in the output can be fed straight back into the generic update tool's offset. numbered is meaningful only with raw=True: combining it with raw=False raises ValueError (like offset/limit), and a numbered read of a document that fails to parse returns the ParseFailureResult described above, never numbered text. Numbered output must never be fed back verbatim into content for update or create_sysrs -- strip the "<n>: " prefix from each line first (it is likewise never a valid edit old_str).

get_sysrs_exampleA

Return a complete, valid sample System Requirements Specification document as raw markdown -- frontmatter and body -- exercising every section, for use as a learning example.

get_sysrs_templateA

Return a SYSRS document template -- frontmatter and every body field present, populated with short placeholder ('blind text') content -- as raw markdown, for use as a starting point when drafting a new System Requirements Specification.

list_sysrsA

Ids, titles, statuses, and refs of System Requirements Specifications in the configured System Requirements Specification base directory, one page at a time, for context before addressing one by id. 'ref' is an opaque, extensionless identifier -- not a filename to read from disk -- for documents that have no assigned id; use it with the get_sysrs tool instead. An optional glob pattern (e.g. 'dead*') filters the listing to the System Requirements Specifications whose id matches it, case-insensitively; glob=None (the default) lists everything, and an empty string matches nothing. max_results/offset control paging (default page size 25, capped at 100); out-of-range values are clamped, not errored.

parse_sysrsA

Parse a System Requirements Specification markdown file (YAML frontmatter + body) from disk into a structured :class:~biz.dfch.specmgr.sysrs.models.v1.SysrsDocument. An existing file that fails to parse returns a non-raising ValidateResult (valid=False, a single errors[].message capped at 300 chars as the generic validate tool caps it, feat-110) instead of raising AssertionError/pydantic.ValidationError/yaml.YAMLError (ADR f14f125e-eaad-4f4f-a6fd-3c931bed726e, GitHub issue #204 -- case 5 of the ADR 519d1206 non-raising-structured-result workaround chain); a truly-absent or unreadable path still raises the OSError-family file-access error (FileNotFoundError/PermissionError/OSError) from Path.read_text().

create_ucA

Create a new use case: assigns a fresh id, derives a filename from the body's H1 title, validates the submitted body-only content, and writes the new document to the use-case base directory. A content-validation failure of the submitted body returns a non-raising ValidateResult (valid=False, a single errors[].message capped at 300 chars as the generic validate tool caps it, feat-110) instead of raising AssertionError/pydantic.ValidationError (ADR f14f125e-eaad-4f4f-a6fd-3c931bed726e, GitHub issue #204 -- case 5 of the ADR 519d1206 non-raising-structured-result workaround chain); nothing is written in that case. Returns the newly created document's frontmatter only (no body); use the corresponding get_uc tool to fetch the full document afterward.

get_ucA

Read, parse, and return a full use-case document (frontmatter and body) by its id. Pass raw=True to return the frontmatter-stripped body text verbatim instead. With raw=True, optional read-style offset/limit window the raw read: offset (1-based, default 1) is the first body line to return, limit (line count, default through end of body) how many; out-of-range values clamp (offset > N returns the empty string), and coordinates with raw=False raise ValueError. A document that exists but fails to parse returns a ParseFailureResult (error/path/id) instead of raising; its error text is byte-identical to the domain's own list tool's failed-row error for the same file (identical field path and cause, including the trailing pydantic documentation line; ADR 9080b37c-82b3-4f63-81f1-79641d0bf14c). An invalid id (path-injection attempt or wrong format) is also a ValueError, raised before any file access. With raw=True, an optional numbered=True prefixes every returned body line with its 1-based absolute body-line number in the "<n>: " form (plain decimal, no padding) -- under offset/limit windowing the numbers start at the clamped offset and never restart at 1, so a number seen in the output can be fed straight back into the generic update tool's offset. numbered is meaningful only with raw=True: combining it with raw=False raises ValueError (like offset/limit), and a numbered read of a document that fails to parse returns the ParseFailureResult described above, never numbered text. Numbered output must never be fed back verbatim into content for update or create_uc -- strip the "<n>: " prefix from each line first (it is likewise never a valid edit old_str).

get_uc_diagramA

Render and return the deterministic PlantUML usecase diagram for one use case (the frozen rulebook specmgr://uc/plantuml §2.5): one usecase node (title + level stereotype), one actor node per distinct cleaned actor label, plain associations. Read-only: the id is path-safety-guarded (a wrong-format id is a ValueError before any file access) and the document is read cache-aware; a document that exists but fails to parse returns the non-raising ParseFailureResult (error/path/id, the feat-150 precedent), and a truly absent id raises the domain's not-found error. Returns PlantUML source (not a specmgr document) -- run it through the validate_plantuml tool for a validation verdict.

get_uc_exampleA

Return a complete, valid sample use case document as raw markdown -- frontmatter and body -- exercising every section, for use as a learning example.

get_uc_plantuml_exampleA

Return the complete, fully attributed PlantUML sequence diagram for the packaged 'Buy Goods' example UC as raw PlantUML source, verbatim -- the model for the generate_uc_sequence_diagram prompt flow (rulebook §2.9 attribution, every UNATTRIBUTED marker resolved). The file is not markdown and not a specmgr document (no frontmatter, not validate-able). Reads the packaged data file fresh on every call.

get_uc_plantuml_templateA

Return the packaged PlantUML sequence-skeleton template (placeholder participants and mapping comments -- the shape get_uc_sequence_skeleton emits, rulebook §2.9) as raw PlantUML source, verbatim. The file is not markdown and not a specmgr document (no frontmatter, not validate-able). Reads the packaged data file fresh on every call.

get_uc_sequence_skeletonA

Render and return the deterministic PlantUML sequence-diagram skeleton for one use case (the frozen rulebook specmgr://uc/plantuml §2.9): participants, the preconditions note, the trigger (virtual step 0, receiver fixed to the system), the ordinal steps, the alt fragments, the final notes -- and every message the §2.9.3 attribution rule cannot pre-fill as one of the three frozen UNATTRIBUTED marker lines. Read-only: the id is path-safety-guarded (a wrong-format id is a ValueError before any file access) and the document is read cache-aware; a document that exists but fails to parse returns the non-raising ParseFailureResult (error/path/id, the feat-150 precedent), and a truly absent id raises the domain's not-found error. The skeleton is the starting point of the generate_uc_sequence_diagram prompt flow (the agent attributes the markers, validates via validate_plantuml, and writes the .puml file host-native; no specmgr tool writes .puml).

get_uc_templateA

Return a UC document template -- frontmatter and every body field present, populated with short placeholder ('blind text') content -- as raw markdown, for use as a starting point when drafting a new use case.

list_ucA

Ids, titles, statuses, and refs of use cases in the configured use-case base directory, one page at a time, for context before addressing one by id. 'ref' is an opaque, extensionless identifier -- not a filename to read from disk -- for documents that have no assigned id; use it with the get_uc tool instead. An optional glob pattern (e.g. 'dead*') filters the listing to the use cases whose id matches it, case-insensitively; glob=None (the default) lists everything, and an empty string matches nothing. max_results/offset control paging (default page size 25, capped at 100); out-of-range values are clamped, not errored.

get_use_case_package_diagramA

Render and return the deterministic PlantUML package diagram for a set of use cases (the frozen rulebook specmgr://uc/plantuml §2.7): one usecase node per document in the given order, the deduplicated actor union, and the <<include>>/<<extend>>/superordinate edges from Related Use Cases. ids=None = every UC in list_uc order (list_uc failed rows -- existing-but-broken documents -- become skipped slots); an id missing on disk or existing-but-broken becomes the same skipped slot, and any reference that does not resolve to a parsed slot in the package (including legacy UC-NNN tokens) takes the deterministic 'Unresolved UC reference' note -- the render never fails on an id or a reference. Read-only: every given id is path-safety-guarded (a wrong-format id is a ValueError before any file access) and the documents are read cache-aware. Returns PlantUML source -- run it through the validate_plantuml tool for a validation verdict.

parse_ucB

Parse a use-case markdown file (YAML frontmatter + body) from disk into a structured document. An existing file that fails to parse returns a non-raising ValidateResult (valid=False, a single errors[].message capped at 300 chars as the generic validate tool caps it, feat-110) instead of raising AssertionError/pydantic.ValidationError/yaml.YAMLError (ADR f14f125e-eaad-4f4f-a6fd-3c931bed726e, GitHub issue #204 -- case 5 of the ADR 519d1206 non-raising-structured-result workaround chain); a truly-absent or unreadable path still raises the OSError-family file-access error (FileNotFoundError/PermissionError/OSError) from Path.read_text().

plantuml_encodeA

Encode PlantUML (or any) text to the PlantUML classic URL encoding (custom-base64 0-9A-Za-z-_ over the raw-deflate stream of the text's UTF-8 bytes, no prefix -- the SoWkI... form, rulebook §5.1). Returns the encoding itself, i.e. the {enc} payload of GET {base}/svg/{enc} -- the tool takes no base URL, so prepend the configured server base (SPECMGR_PLANTUML_URL for the url source) to build the renderable URL. Fully offline: no source, subprocess, or network is involved. Decode it back with the library's decode_puml (round-trip lossless).

validate_plantumlA

Validate PlantUML diagram text through the strict validation chain (the frozen rulebook specmgr://uc/plantuml §3): the structure check always runs first (on a structure red the parser is never called -- no subprocess, no network), then the single configured source (the first set of SPECMGR_PLANTUML_JAR/SPECMGR_PLANTUML_BIN/SPECMGR_PLANTUML_URL; no fall-through -- a set-but-unavailable source is a hard failure with reason + fix hint), and the all-unset state degrades to the structure-only floor. A PlantUML server crash page (200 + the embedded Java-exception trace -- the recognised 1.2026.8 crash line of the rulebook §5.2 matrix, the known self-message/note-left shape bug) is a recognised INVALID row: valid=false with the line-0 crash finding carrying the exception class and a fix hint pointing at the rulebook §2.9 anchored notes. Content-based: pass the diagram text (a CLI reads the file and passes its text). Never raises for validation content -- returns the non-raising §3.6 result model: structure_ok, valid/rendered (None = not run, never run-and-failed), checked_by (jar/bin/url/structure), errors and warnings (1-based line + message + fix hint), source_state (ok/misconfigured/unavailable/inconclusive/none), available, reason, fix_hint.

create_vcrA

Create a new verification case record: assigns a fresh id, derives a filename from the body's H1 title, validates the submitted body-only content, and writes the new document to the verification case record base directory. A content-validation failure of the submitted body returns a non-raising ValidateResult (valid=False, a single errors[].message capped at 300 chars as the generic validate tool caps it, feat-110) instead of raising AssertionError/pydantic.ValidationError (ADR f14f125e-eaad-4f4f-a6fd-3c931bed726e, GitHub issue #204 -- case 5 of the ADR 519d1206 non-raising-structured-result workaround chain); nothing is written in that case. Returns the newly created document's frontmatter only (no body); use the corresponding get_vcr tool to fetch the full document afterward.

get_vcrA

Read, parse, and return a full verification case record document (frontmatter and body) by its id. Pass raw=True to return the frontmatter-stripped body text verbatim instead. With raw=True, optional read-style offset/limit window the raw read: offset (1-based, default 1) is the first body line to return, limit (line count, default through end of body) how many; out-of-range values clamp (offset > N returns the empty string), and coordinates with raw=False raise ValueError. A document that exists but fails to parse returns a ParseFailureResult (error/path/id) instead of raising; its error text is byte-identical to the domain's own list tool's failed-row error for the same file (identical field path and cause, including the trailing pydantic documentation line; ADR 9080b37c-82b3-4f63-81f1-79641d0bf14c). An invalid id (path-injection attempt or wrong format) is also a ValueError, raised before any file access. With raw=True, an optional numbered=True prefixes every returned body line with its 1-based absolute body-line number in the "<n>: " form (plain decimal, no padding) -- under offset/limit windowing the numbers start at the clamped offset and never restart at 1, so a number seen in the output can be fed straight back into the generic update tool's offset. numbered is meaningful only with raw=True: combining it with raw=False raises ValueError (like offset/limit), and a numbered read of a document that fails to parse returns the ParseFailureResult described above, never numbered text. Numbered output must never be fed back verbatim into content for update or create_vcr -- strip the "<n>: " prefix from each line first (it is likewise never a valid edit old_str).

get_vcr_exampleA

Return a complete, valid sample verification case record document as raw markdown -- frontmatter and body -- exercising every section, for use as a learning example.

get_vcr_templateA

Return a VCR document template -- frontmatter and every body field present, populated with short placeholder ('blind text') content -- as raw markdown, for use as a starting point when drafting a new verification case record.

list_vcrA

Ids, titles, statuses, and refs of verification case records in the configured verification case record base directory, one page at a time, for context before addressing one by id. 'ref' is an opaque, extensionless identifier -- not a filename to read from disk -- for documents that have no assigned id; use it with the get_vcr tool instead. An optional glob pattern (e.g. 'dead*') filters the listing to the verification case records whose id matches it, case-insensitively; glob=None (the default) lists everything, and an empty string matches nothing. max_results/offset control paging (default page size 25, capped at 100); out-of-range values are clamped, not errored.

parse_vcrA

Parse a verification case record markdown file (YAML frontmatter + body) from disk into a structured :class:~biz.dfch.specmgr.vcr.models.v1.VcrDocument. An existing file that fails to parse returns a non-raising ValidateResult (valid=False, a single errors[].message capped at 300 chars as the generic validate tool caps it, feat-110) instead of raising AssertionError/pydantic.ValidationError/yaml.YAMLError (ADR f14f125e-eaad-4f4f-a6fd-3c931bed726e, GitHub issue #204 -- case 5 of the ADR 519d1206 non-raising-structured-result workaround chain); a truly-absent or unreadable path still raises the OSError-family file-access error (FileNotFoundError/PermissionError/OSError) from Path.read_text().

create_decA

Create a new decision: assigns a fresh id, derives a filename from the body's H1 title, validates the submitted body-only content, and writes the new document to the decision base directory. A content-validation failure of the submitted body returns a non-raising ValidateResult (valid=False, a single errors[].message capped at 300 chars as the generic validate tool caps it, feat-110) instead of raising AssertionError/pydantic.ValidationError (ADR f14f125e-eaad-4f4f-a6fd-3c931bed726e, GitHub issue #204 -- case 5 of the ADR 519d1206 non-raising-structured-result workaround chain); nothing is written in that case. Returns the newly created document's frontmatter only (no body); use the corresponding get_dec tool to fetch the full document afterward.

get_decA

Read, parse, and return a full decision document (frontmatter and body) by its id. Pass raw=True to return the frontmatter-stripped body text verbatim instead. With raw=True, optional read-style offset/limit window the raw read: offset (1-based, default 1) is the first body line to return, limit (line count, default through end of body) how many; out-of-range values clamp (offset > N returns the empty string), and coordinates with raw=False raise ValueError. A document that exists but fails to parse returns a ParseFailureResult (error/path/id) instead of raising; its error text is byte-identical to the domain's own list tool's failed-row error for the same file (identical field path and cause, including the trailing pydantic documentation line; ADR 9080b37c-82b3-4f63-81f1-79641d0bf14c). An invalid id (path-injection attempt or wrong format) is also a ValueError, raised before any file access. With raw=True, an optional numbered=True prefixes every returned body line with its 1-based absolute body-line number in the "<n>: " form (plain decimal, no padding) -- under offset/limit windowing the numbers start at the clamped offset and never restart at 1, so a number seen in the output can be fed straight back into the generic update tool's offset. numbered is meaningful only with raw=True: combining it with raw=False raises ValueError (like offset/limit), and a numbered read of a document that fails to parse returns the ParseFailureResult described above, never numbered text. Numbered output must never be fed back verbatim into content for update or create_dec -- strip the "<n>: " prefix from each line first (it is likewise never a valid edit old_str).

get_dec_exampleA

Return a complete, valid sample decision document as raw markdown -- frontmatter and body -- exercising every section, for use as a learning example.

get_dec_templateA

Return a DEC document template -- frontmatter and every body field present, populated with short placeholder ('blind text') content -- as raw markdown, for use as a starting point when drafting a new decision.

list_decA

Ids, titles, statuses, and refs of decisions in the configured decision base directory, one page at a time, for context before addressing one by id. 'ref' is an opaque, extensionless identifier -- not a filename to read from disk -- for documents that have no assigned id; use it with the get_dec tool instead. An optional glob pattern (e.g. 'dead*') filters the listing to the decisions whose id matches it, case-insensitively; glob=None (the default) lists everything, and an empty string matches nothing. max_results/offset control paging (default page size 25, capped at 100); out-of-range values are clamped, not errored.

parse_decA

Parse a decision markdown file (YAML frontmatter + body) from disk into a structured :class:~biz.dfch.specmgr.dec.models.v1.DecDocument. An existing file that fails to parse returns a non-raising ValidateResult (valid=False, a single errors[].message capped at 300 chars as the generic validate tool caps it, feat-110) instead of raising AssertionError/pydantic.ValidationError/yaml.YAMLError (ADR f14f125e-eaad-4f4f-a6fd-3c931bed726e, GitHub issue #204 -- case 5 of the ADR 519d1206 non-raising-structured-result workaround chain); a truly-absent or unreadable path still raises the OSError-family file-access error (FileNotFoundError/PermissionError/OSError) from Path.read_text().

validateA

Disk-free, id-free dry run validating document content across the whole-body domains (type is one of req, uc, tsk, qa, prb, gol, rsk, dec, sop, feat, vcr, sysrs; adr is not supported -- use validate_adr instead). full=False (default) validates body-only content (no frontmatter); full=True validates a complete document (frontmatter + body). Never raises for a content-validation failure: always returns {valid: bool, errors: list[{message: str}]} -- errors is empty when valid is True, and each message is truncated to at most _MAX_VALIDATE_ERROR_CHARS (300) characters (plus an "... (truncated)" suffix when truncation occurred) rather than returned verbatim without limit. A full/content-shape mismatch, or an unsupported type, is a caller-usage error and still raises ValueError before any validation runs. This is the sole validate entry point for these domains -- the former per-domain validate_<d> tools are removed; validate_adr remains a separate, unchanged, id-based tool.

create_featA

Create a new feature: assigns a fresh id (caller-chosen via the optional 'id' parameter, or defaulted to feat-0- when omitted -- no max+1 auto-generation), derives a filename from the body's H1 title, validates the submitted body-only content, and writes the new document to the feature base directory. A content-validation failure of the submitted body returns a non-raising ValidateResult (valid=False, a single errors[].message capped at 300 chars as the generic validate tool caps it, feat-110) instead of raising AssertionError/pydantic.ValidationError (ADR f14f125e-eaad-4f4f-a6fd-3c931bed726e, GitHub issue #204 -- case 5 of the ADR 519d1206 non-raising-structured-result workaround chain); nothing is written in that case. Content validation runs BEFORE the id-shape ValueError and already-existing-id/folder FileExistsError guards, so a compound failure (invalid content + a malformed or already-existing id) returns the ValidateResult and the guard never runs in that call; each guard still raises whenever the content is valid. Returns the newly created document's frontmatter only (no body); use the corresponding get_feat tool to fetch the full document afterward.

get_featA

Read, parse, and return a full feature document (frontmatter and body) by its id. Pass raw=True to return the frontmatter-stripped body text verbatim instead. With raw=True, optional read-style offset/limit window the raw read: offset (1-based, default 1) is the first body line to return, limit (line count, default through end of body) how many; out-of-range values clamp (offset > N returns the empty string), and coordinates with raw=False raise ValueError. A document that exists but fails to parse returns a ParseFailureResult (error/path/id) instead of raising; get_feat always fully parses, so its error text is the full-fidelity authority for this document -- byte-identical to list_feat's own failed-row error for the same file once list_feat's background warmup (or this very call) has fully parsed it; before that (or under SPECMGR_FEAT_WARMUP_DISABLED), list_feat's row may carry a transiently-healthy or dirty-stage-specific error instead (ADR 3982712a-a46b-4b2b-809f-9c6925a49b44, time-qualifying ADR 9080b37c-82b3-4f63-81f1-79641d0bf14c for feat only; every other domain's list/get error byte-identity stays unconditional). An invalid id (path-injection attempt or wrong format) is also a ValueError, raised before any file access. With raw=True, an optional numbered=True prefixes every returned body line with its 1-based absolute body-line number in the "<n>: " form (plain decimal, no padding) -- under offset/limit windowing the numbers start at the clamped offset and never restart at 1, so a number seen in the output can be fed straight back into the generic update tool's offset. numbered is meaningful only with raw=True: combining it with raw=False raises ValueError (like offset/limit), and a numbered read of a document that fails to parse returns the ParseFailureResult described above, never numbered text. Numbered output must never be fed back verbatim into content for update or create_feat -- strip the "<n>: " prefix from each line first (it is likewise never a valid edit old_str).

get_feat_exampleA

Return a complete, valid sample feature document as raw markdown -- frontmatter and body -- exercising every section, for use as a learning example.

get_feat_templateA

Return a FEAT document template -- frontmatter and every body field present, populated with short placeholder ('blind text') content -- as raw markdown, for use as a starting point when drafting a new feature.

list_featA

Ids, titles, statuses, and refs of features in the configured feature base directory, one page at a time, for context before addressing one by id. 'ref' is an opaque, extensionless identifier -- not a filename to read from disk -- for documents that have no assigned id; use it with the get_feat tool instead. An optional glob pattern (e.g. 'feat-7*') filters the listing to the features whose id matches it, case-insensitively; glob=None (the default) lists everything, and an empty string matches nothing. max_results/offset control paging (default page size 25, capped at 100); out-of-range values are clamped, not errored. The request path never fully parses a document's body (GitHub issue #187): a folder's row is resolved from its frontmatter+H1 alone until a background warmup (or an on-demand get_feat read) has fully parsed it, so a body-level parse failure may transiently appear healthy, and a missing/wrong-shape H1's error text may transiently differ from get_feat's -- both converge to get_feat's exact error once that file has been fully parsed. Set SPECMGR_FEAT_WARMUP_DISABLED to turn the background warmup off entirely (convergence then depends solely on on-demand reads).

parse_featA

Parse a feature markdown file (YAML frontmatter + body) from disk into a structured :class:~biz.dfch.specmgr.feat.models.v1.FeatDocument. An existing file that fails to parse returns a non-raising ValidateResult (valid=False, a single errors[].message capped at 300 chars as the generic validate tool caps it, feat-110) instead of raising AssertionError/pydantic.ValidationError/yaml.YAMLError (ADR f14f125e-eaad-4f4f-a6fd-3c931bed726e, GitHub issue #204 -- case 5 of the ADR 519d1206 non-raising-structured-result workaround chain); a truly-absent or unreadable path still raises the OSError-family file-access error (FileNotFoundError/PermissionError/OSError) from Path.read_text().

set_feat_idA

Rename an existing feature's id: validates new_id's feat-NNN-slug shape, refuses if new_id's folder already exists, renames // to /<new_id>/, rewrites the README frontmatter id to new_id, bumps updated, and leaves the body byte-identical. Does not update or search for references to the old id in any other document. Returns the renamed document's frontmatter only (no body); use the corresponding get_feat tool to fetch the full document afterward.

deleteA

Permanently delete an existing document from disk across the whole-body domains (type is one of req, uc, tsk, qa, prb, gol, rsk, dec, sop, feat, vcr, sysrs; adr is not supported). Resolves the document by id, takes the domain lock, and removes it: the single *.md file for every flat domain (every whole-body domain except feat), or the entire <base>/<id>/ folder for feat. Returns the deleted path as a string. An invalid id (path-injection attempt or wrong format) is a ValueError raised before any file access; a missing document is the domain's own XNotFoundError; an I/O failure is a DeleteError. This is the sole delete entry point -- the former per-domain delete_<d> tools are removed.

editA

Surgical, exact-match string replacement of an existing document's frontmatter-stripped body across the whole-body domains (type is one of req, uc, tsk, qa, prb, gol, rsk, dec, sop, feat, vcr, sysrs; adr is not supported -- an explicit pre-dispatch ValueError, unlike update's inherited KeyError). Read the current body via the corresponding get_<d>(id, raw=True) first -- the read-before-edit step is a client convention, not server-enforced. Use edit for a surgical string replacement within an existing body; use the generic update tool for a whole-body or line-range replacement instead. The YAML frontmatter is never addressable (body only). The edit is 2-fold: stage 1 requires old_str to match the on-disk body byte-exactly -- uniquely, unless replace_all is true, in which case every exact occurrence is rewritten -- and stage 2 validates the edited body as a whole document; the document is written to disk only if both stages pass, and nothing is written on any failure (the file stays byte-unchanged). An empty new_str is a pure deletion (legal iff stage 2 validates). Matching is pure byte-exact with no line-ending normalization (an old_str containing \n will not match a CRLF body), no BOM handling, and no fuzzy/regex fallback. A document that exists but fails to parse returns a ParseFailureResult (error/path/id) instead of raising the domain's not-found error -- its error text is byte-identical to the domain's list_<d> failed row's error for the same file (identical field path and cause, including the trailing pydantic documentation line; ADR 9080b37c-82b3-4f63-81f1-79641d0bf14c) -- and a truly-absent id still raises the domain's not-found error. A stage-2 content-validation failure on the post-edit result returns a non-raising ValidateResult (valid=False, errors=[{message}]) with the message capped at 300 chars as the generic validate tool caps it, instead of raising AssertionError/pydantic.ValidationError (ADR b8c9bfea-6dcf-4158-bfc5-4ec17abb842f, GitHub issue #170 -- case 4 of the ADR 519d1206 non-raising-structured-result workaround chain). Stage-1's not-found/multiple-matches guards and every caller-usage ValueError (invalid id shape, unknown or adr type, identical input, empty old_str) still raise. An invalid id (path-injection attempt or wrong format for type) is a ValueError raised before any file access. Returns the updated frontmatter only (no body; updated bumped) on success; use the corresponding get_<d> tool to fetch the full document afterward.

find_relatedA

Find the documents most semantically related to an existing document, given its type/id, ranked by cosine similarity of local sentence embeddings (fastembed/bge-small, the similarity extra). By default every whole-body domain is searched (req, uc, tsk, qa, prb, gol, rsk, dec, sop, feat, vcr, sysrs; adr is excluded structurally) -- restrict with target_types; the source document itself is excluded from the results. Returns up to top_k (default 10, validated 1..100) hits as {type, id, title, status, path, score} rows, sorted by score descending; min_score (default: no filter) is an inclusive cosine lower bound. An unparseable candidate still appears, embedded from its full raw text, with id = null and the <failed to parse> marker title/status. When the embedding feature is unavailable (SPECMGR_SIMILARITY_DISABLED present, or the backend/model fails to load), returns the structured {available: false, reason, message} result instead of raising. A bad type/id/target_types/top_k is a ValueError before any filesystem access; a missing source is the domain's own XNotFoundError.

find_similar_textA

Find the documents most semantically similar to a free-form query text (for pre-creation dedup/discovery checks), ranked by cosine similarity of local sentence embeddings (fastembed/bge-small, the similarity extra). By default every whole-body domain is searched (req, uc, tsk, qa, prb, gol, rsk, dec, sop, feat, vcr, sysrs; adr is excluded structurally) -- restrict with target_types. Returns up to top_k (default 10, validated 1..100) hits as {type, id, title, status, path, score} rows, sorted by score descending; min_score (default: no filter) is an inclusive cosine lower bound. An unparseable candidate still appears, embedded from its full raw text, with id = null and the <failed to parse> marker title/status. When the embedding feature is unavailable (SPECMGR_SIMILARITY_DISABLED present, or the backend/model fails to load), returns the structured {available: false, reason, message} result instead of raising. A bad target_types/top_k is a ValueError before any filesystem access.

create_adrB

Create a new ADR: assigns a fresh id, derives a filename from the title, validates, renders, and writes the new document to the ADR base directory.

get_adrA

Read, parse, and return a full ADR document (frontmatter and body) by its id. An invalid id (path-injection attempt or wrong format) is a ValueError raised before any file access.

list_adrA

Ids, titles, statuses, and refs of ADRs in the configured ADR base directory (SPECMGR_ADR_DIR), one page at a time, for context before addressing one by id. 'ref' is an opaque, extensionless identifier -- not a filename to read from disk -- for documents that have no assigned id; use get_adr with it instead. max_results/offset control paging (default page size 25, capped at 100); out-of-range values are clamped, not errored.

option_createB

Append a new 'Option N: ...' sub-section (plan §5), returning its assigned full title.

option_deleteC

Remove the option named full_title (plan §5), returning the remaining full titles.

option_listC

Full titles of every current 'Option N: ...' sub-section, in document order (plan §5).

option_readC

Return the current content of the option named full_title (plan §5).

option_updateB

Full-content replace of the option named full_title (plan §5), returning the new content.

update_frontmatterB

Whole-object replace of an ADR's frontmatter (plan §3), preserving its existing id.

update_sectionD

Whole-section replace/delete of one AdrBody field (plan §4).

validate_adrB

Re-read and re-parse an ADR by id, letting the models' own Pydantic validators run.

get_reference_diagramA

Render and return the deterministic PlantUML component diagram of one source document's reference neighbourhood (the frozen rulebook specmgr://reference-graph §2–§5): one node per artifact (label = the document title, truncated to SPECMGR_DIAGRAM_MAX_TITLE, default 40), a stereotype + colour per artifact type, nodes grouped into per-domain packages, one edge per unique reference ({src} --> {dst} : refers to, the referenced item carries the incoming arrow), every edge lying on a cycle (SCC-based) drawn with the red -[#red]-> arrow, and every reference whose target cannot be resolved on disk drawn as a top-level <<UNRESOLVED>> node. type is the source document's domain (one of adr, req, uc, tsk, qa, prb, gol, rsk, dec, sop, feat, vcr, sysrs) and id the source's own identifier; depth (1..5, default 1) is the forward BFS depth; reverse=True is additive (the forward expansion to depth plus the direct incoming references to the source, direct-only on the incoming side); include_feat=False drops every FEAT node except the explicitly requested source (then every edge touching a dropped node); title overrides the diagram title (default: the source's H1; sanitized but never truncated). Guard order: id (path-injection attempt or wrong format -- for type="feat" the full feat-NNN-slug only; a bare feat-NNN is rejected, use list_feat to discover the exact id) and depth are both a ValueError raised before any filesystem access; a missing source raises the source domain's own XNotFoundError; an existing-but-broken source returns the non-raising ParseFailureResult (error/path/id, the error text byte-identical to the domain's list_<d> failed-row error for the same file (ADR 9080b37c) for the 12 whole-body domains -- time-qualified by ADR 3982712a for feat; for adr (whose list_adr carries no failed row: broken ADRs are skipped), the leg-read AdrParseError's own text). Returns PlantUML source (not a specmgr document) -- run it through specmgr plantuml-check (CLI) or the validate_plantuml tool for a validation verdict.

get_reference_diagram_allA

Render and return the deterministic PlantUML component diagram of the whole reference registry (the frozen rulebook specmgr://reference-graph §2–§5, the registry-wide construction of §3.3): one node per parseable document across all 13 domains (broken documents are skipped -- the render never fails for content), one edge per unique reference ({src} --> {dst} : refers to, the referenced item carries the incoming arrow), every edge lying on a cycle (SCC-based) drawn with the red -[#red]-> arrow, and every reference whose target cannot be resolved on disk drawn as a top-level <<UNRESOLVED>> node. Node labels are truncated to SPECMGR_DIAGRAM_MAX_TITLE (default 40). include_feat=False drops every FEAT node (then every edge touching a dropped node); title overrides the diagram title (default: Reference Graph; sanitized but never truncated). Returns PlantUML source (not a specmgr document) -- run it through specmgr plantuml-check (CLI) or the validate_plantuml tool for a validation verdict.

list_referencesA

Cross-references of one source document, resolved and paged. type is the source document's domain (one of adr, req, uc, tsk, qa, prb, gol, rsk, dec, sop, feat, vcr, sysrs) and id the source's own identifier. The tool scans the source's frontmatter-stripped body for reference tags (the shared reference-tag vocabulary in general.tools._references: the UUID tags GOL/PRB/QA/UC/REQ/RSK/DEC/ADR/VCR/SYSRS, each carrying a canonical uuid id, plus FEAT, carrying the full feat-NNN-slug id or the bare feat-NNN number; case-insensitive tag, space/tab/dash separator, anywhere in a line), dedupes repeated occurrences (first-occurrence order preserved), and resolves each unique reference to the referenced document in its own target domain. Returns a PagedResult of one ReferenceRow per unique reference: type, id, title (the referenced document's H1), and path (the referenced document's resolved absolute file path). A reference that cannot be resolved on disk is a row with null title/path and the target domain's not-found message in error -- it never raises. max_results/offset control paging (default page size 25, capped at 100); out-of-range values are clamped, not errored. An invalid id (path-injection attempt or wrong format for type) is a ValueError raised before any file access; a missing source document is the source domain's own XNotFoundError.

mdformatA

Format a markdown file in place, preserving any YAML frontmatter. Returns True if the file was changed, False if already formatted.

set_classificationA

Replace the free-text classification frontmatter field of an existing document across the whole-body domains (type is one of req, uc, tsk, qa, prb, gol, rsk, dec, sop, feat, vcr, sysrs; adr is not supported), also bumping updated and leaving the body and every other frontmatter field untouched. classification is fully free-text -- no closed vocabulary; a blank or whitespace-only value clears it back to None/absent. No create_* tool accepts a classification argument at all -- this is the sole classification-change entry point. A document that exists but fails to parse returns a ParseFailureResult (error/path/id) instead of raising the domain's not-found error (a truly-absent id still raises) -- its error text is byte-identical to the domain's list_<d> failed row's error for the same file (identical field path and cause, including the trailing pydantic documentation line; ADR 9080b37c-82b3-4f63-81f1-79641d0bf14c; ADR b8c9bfea-6dcf-4158-bfc5-4ec17abb842f, GitHub issue #170 -- case 4 of the ADR 519d1206 non-raising-structured-result workaround chain). An invalid id (path-injection attempt or wrong format for type) or an unknown type is a ValueError raised before any file access; type="adr" passes the id validation (a well-formed UUID id) and raises the plain KeyError inherited from the dispatch-table lookup instead. Returns the updated frontmatter only (no body) on success; use the corresponding get_<d> tool to fetch the full document afterward.

set_statusA

Replace the status of an existing document across every domain (type is one of adr, req, uc, tsk, qa, prb, gol, rsk, dec, sop, feat, vcr, sysrs), also bumping updated (the whole-body domains) and leaving the body untouched. When status (or, for type="adr" with superseded_by given, the composed "superseded by X" value) already equals the document's current status, this is a no-op -- no write, no updated bump -- and still returns the same value shape a changed-status call would (issue #109). The new status must be one of the domain's own closed vocabulary values (see the domain's XFrontmatter.status field); an out-of-vocabulary status does NOT raise -- it returns a structured, non-raising InvalidStatusResult ({valid: false, type, status, allowed_values, message}) instead, so the allowed-values detail survives MCP clients that truncate error content. superseded_by is accepted only for type="adr" -- it composes the status as "superseded by {superseded_by}"; with any other type it is a ValueError. A document that exists but fails to parse returns a ParseFailureResult (error/path/id) instead of raising the domain's not-found error (a truly-absent id still raises, and the out-of-vocabulary-status InvalidStatusResult check above still runs first, pre-lock/pre-load) -- its error text is byte-identical to the domain's list_<d> failed row's error for the same file (identical field path and cause, including the trailing pydantic documentation line; ADR 9080b37c-82b3-4f63-81f1-79641d0bf14c; ADR b8c9bfea-6dcf-4158-bfc5-4ec17abb842f, GitHub issue #170 -- case 4 of the ADR 519d1206 non-raising-structured-result workaround chain). Neither create_* nor the generic update tool accepts a status argument at all -- this is the sole status-change entry point. An invalid id (path-injection attempt or wrong format for type) is a ValueError raised before any file access. Returns the updated frontmatter only (no body, except for the unchanged adr branch) on success; use the corresponding get_<d> tool to fetch the full document afterward.

updateA

Whole-body or line-range replace of an existing document's content across the whole-body domains (type is one of req, uc, tsk, qa, prb, gol, rsk, dec, sop, feat, vcr, sysrs), preserving its id/type/status/created/version; only updated changes. With no offset/limit, content is the full replacement body (body markdown only, no frontmatter block). With offset, content replaces the body line(s) starting at 1-based line offset of the current on-disk body: limit is the number of lines to replace (offset..offset+limit-1; limit omitted = through the last body line, limit=0 = pure insert), and offset=N+1 (one past the last body line) appends after it; the spliced result is validated as a whole document before anything is written. offset/limit address the frontmatter-stripped body, never the raw on-disk .md file: the YAML frontmatter block is variable-length, so a raw file read's line numbers are never the same as body-line coordinates -- the only safe source of coordinates is a get_<d>(id, raw=True) read, never a raw file read minus an assumed constant. A get_<d>(raw=True, numbered=True) read's numbered output must never be fed back verbatim into content -- strip the "<n>: " prefix from each line first (it is likewise never a valid edit old_str). status is never settable -- use the generic set_status tool. A document that exists but fails to parse returns a ParseFailureResult (error/path/id) instead of raising the domain's not-found error -- its error text is byte-identical to the domain's list_<d> failed row's error for the same file (identical field path and cause, including the trailing pydantic documentation line; ADR 9080b37c-82b3-4f63-81f1-79641d0bf14c) -- and a truly-absent id still raises the domain's not-found error. A content-validation failure on the submitted new content (or, in range mode, on the spliced result) returns a non-raising ValidateResult (valid=False, errors=[{message}]) with the message capped at 300 chars as the generic validate tool caps it, instead of raising AssertionError/pydantic.ValidationError (ADR b8c9bfea-6dcf-4158-bfc5-4ec17abb842f, GitHub issue #170 -- case 4 of the ADR 519d1206 non-raising-structured-result workaround chain). An invalid id (path-injection attempt or wrong format for type) or misused range coordinates (limit without offset) is a ValueError raised before any file access. Returns an UpdateResult: frontmatter, the updated frontmatter (no body) of the dispatched domain, plus snippet -- in range mode, the before/after window of the touched range (dropped lines numbered pre-splice, inserted lines numbered post-splice, up to 2 unchanged context lines per side, each line <marker> <n>: <line text>); snippet is None in whole-body mode and for the whole-body-equivalent range (offset=1 with limit omitted). Use the corresponding get_<d> tool to fetch the full document afterward.

Prompts

Interactive templates invoked by user choice

NameDescription
create_featGuides the LLM through checking for an existing similar feature, gathering the required information, and driving create_feat/validate to author a new FEAT document.
update_featGuides the LLM through revising an existing feature by id: reading current state, applying the requested change with the right tool, and validating.
create_taskGuides the LLM through checking for an existing similar task list, gathering the required information, and driving create_tsk/validate to author a new TSK document.
implement_taskReads an existing task list by id, builds a TodoWrite list from its items, and uses the question tool to resolve ambiguity before proceeding.
update_taskGuides the LLM through revising an existing task list by id: reading current state, applying the requested change with the right tool, and validating.
create_golGuides the LLM through checking for an existing similar goal, gathering the required information, and driving create_gol/validate to author a new GOL document.
update_golGuides the LLM through revising an existing goal by id: reading current state, showing which sections are present vs. empty, eliciting revisions, applying the change with the right tool, and validating.
create_prbGuides the LLM through checking for an existing similar problem statement, optionally carrying over already-answered 5W2H questions from a linked QA document (qa_id), interviewing the user for whichever 5W2H current-state questions remain, synthesizing the Summary and Gap, composing the mandatory Problem Statement lead sentence, and driving create_prb/validate to author a new PRB document.
update_prbGuides the LLM through revising an existing problem statement by id: reading current state (recovering an old-shape document missing the mandatory lead sentence via a raw re-read if needed), showing which of the 7 5W2H questions are answered, eliciting revisions, re-synthesizing Summary/Gap, applying the change with the right tool, and validating.
create_qaGuides the LLM through checking for an existing similar QA document, gathering answers to ISO/IEC 25010:2023 characteristic-relevant questions, and driving create_qa/validate to author a new QA document.
refineGuides the LLM through appending a batch of new, unanswered interview questions (each numbered with its target category's next `**<d>.<NNNN>**: ` prefix and carrying the `TODO: answer pending` placeholder in place of an answer) to an existing QA document, for `Elicitation Context` or one or more of the nine ISO/IEC 25010:2023 quality characteristics.
update_qaGuides the LLM through revising an existing QA document by id: reading current state, applying the requested change with the right tool, and validating.
create_reqGuides the LLM through checking for an existing similar requirement, gathering the required information, and driving create_req/validate to author a new REQ document.
update_reqGuides the LLM through revising an existing requirement by id: reading current state, applying the requested change with the right tool, and validating.
create_riskGuides the LLM through checking for an existing similar risk, gathering the required information, and driving create_rsk/validate to author a new RSK document.
update_riskGuides the LLM through revising an existing risk by id: reading current state, applying the requested change with the right tool, and validating.
create_sopGuides the LLM through checking for an existing similar SOP, gathering the required information, and driving create_sop/validate to author a new SOP document.
update_sopGuides the LLM through revising an existing SOP by id: reading current state, applying the requested change with the right tool, and validating.
create_sysrsGuides the LLM through checking for an existing similar system requirements specification, gathering the required information, and driving create_sysrs/validate to author a new SYSRS document.
update_sysrsGuides the LLM through revising an existing SYSRS by id: reading current state, applying the requested change with the right tool, and validating.
create_ucGuides the LLM through checking for an existing similar use case, gathering the required information, and driving create_uc/validate to author a new UC document.
generate_uc_sequence_diagramGuides the LLM through the rulebook §3.8 agent flow for one use case: read the frozen rulebook (specmgr://uc/plantuml) first, build a TodoWrite plan, read the UC via get_uc (a ParseFailureResult stops the flow), apply the §2.11 Subfunction judgment, fetch the deterministic skeleton via get_uc_sequence_skeleton, attribute every UNATTRIBUTED marker by understanding the free text (pre-filled arrows are positional, not semantic, and may be corrected; the question tool MUST be used whenever not confident), enforce the zero-marker rule, loop validate_plantuml until green at the highest available layer (source_state != ok with a source set => report reason/fix_hint and do not write; all unset => write with the ' validated: structure-only header), write the .puml file host-native at diagrams/uc/<id>.sequence.puml (no specmgr tool writes .puml), and never commit.
update_ucGuides the LLM through revising an existing use case by id: reading current state, applying the requested change with the right tool, and validating.
create_vcrGuides the LLM through checking for an existing similar verification case record, gathering the required information, and driving create_vcr/validate to author a new VCR document.
update_vcrGuides the LLM through revising an existing verification case record by id: reading current state, applying the requested change with the right tool, and validating.
create_decGuides the LLM through checking for an existing similar decision, gathering the required information, and driving create_dec/validate to author a new DEC document.
update_decGuides the LLM through revising an existing decision by id: reading current state, applying the requested change with the right tool, and validating.
compact_historyGuides the LLM through rotating older 'Recent Updates' entries out of a .specmgr feature folder's README.md and into an optional sibling history.md, leaving a pointer line behind, per ADR e369ee2e-3353-4f92-991c-6367d76d832e.
repairGuides the LLM through repairing a whole-body specmgr document that currently fails to parse: discover it via get_<d>(id)'s non-raising parse-failure result (error/path/id -- the error text byte-identical to list_<d>()'s failed row for the same file; every whole-body domain, ADR 9080b37c-82b3-4f63-81f1-79641d0bf14c -- time-qualified for feat only, ADR 3982712a-a46b-4b2b-809f-9c6925a49b44: list_feat's own row may transiently differ until its background warmup or an on-demand get_feat read has fully parsed that file) when an id is given, or list_<d>()'s '<failed to parse>' failed row without one; read the raw file with the host's own file-read tool, fix only what the error addresses while preserving the frontmatter id/created/status/version byte-for-byte (a repair is not an edit), loop validate(type, content, full=True) until green, write the repaired text back to the same path with the host's own file-write tool (never via the generic update (or edit) tool, which is structurally unable to repair a document that fails to parse), then confirm the repair against the file as it now exists on disk with one more real get_<d>(id)/list_<d>() call (success: the parsed document, not an error-carrying result). Degrades to diagnose-only on a host without file read/write tools. ADR is out of scope.
create_adrGuides the LLM through checking for an existing similar ADR, gathering the required information, and driving create_adr/option_create/set_status/validate_adr to author a new MADR-4.0.0-based Architecture Decision Record.
create_adr_testExperimental, strictly step-gated variant of create_adr for A/B comparison: the same MADR-4.0.0 structure and create_adr/option_create/set_status/validate_adr tool sequence, rewritten as hard numbered gates instead of narrated steps.
update_adrGuides the LLM through revising an existing ADR by id: reading current state, applying the requested change with the right tool, and validating.
update_adr_testExperimental, strictly step-gated variant of update_adr for A/B comparison: the same read-first/map-to-tool/validate-last flow, rewritten as hard numbered gates instead of narrated steps.

Resources

Contextual data attached and managed by the client

NameDescription
feat_exampleA complete, valid sample feature document as raw markdown -- frontmatter and body -- exercising every section, for use as a learning example.
feat_schemaThe generated FEAT JSON Schema (2020-12 dialect), generated by `specmgr schema` and kept current by a pre-commit hook/CI step. Includes a `$comment` schema-layout version marker for detecting a shape change without diffing the whole document.
feat_templateA FEAT document template -- frontmatter and every body field present, populated with short placeholder ('blind text') content -- as raw markdown, for use as a starting point when drafting a new feature.
tsk_exampleA complete, valid sample task list document as raw markdown -- frontmatter and body -- exercising every section, for use as a learning example.
tsk_schemaThe generated TSK JSON Schema (2020-12 dialect), generated by `specmgr schema` and kept current by a pre-commit hook/CI step. Includes a `$comment` schema-layout version marker for detecting a shape change without diffing the whole document.
tsk_templateA TSK document template -- frontmatter and every body field present, populated with short placeholder ('blind text') content -- as raw markdown, for use as a starting point when drafting a new task list.
gol_exampleA complete, valid sample goal document as raw markdown -- frontmatter and body -- exercising every section, for use as a learning example.
gol_schemaThe generated GOL JSON Schema (2020-12 dialect), generated by `specmgr schema` and kept current by a pre-commit hook/CI step. Includes a `$comment` schema-layout version marker for detecting a shape change without diffing the whole document.
gol_templateA GOL document template -- frontmatter and every body field present, populated with short placeholder ('blind text') content -- as raw markdown, for use as a starting point when drafting a new goal.
prb_exampleA complete, valid sample problem statement document as raw markdown -- frontmatter and body -- exercising every section, for use as a learning example.
prb_schemaThe generated PRB JSON Schema (2020-12 dialect), generated by `specmgr schema` and kept current by a pre-commit hook/CI step. Includes a `$comment` schema-layout version marker for detecting a shape change without diffing the whole document.
prb_templateA PRB document template -- frontmatter and every body field present, populated with short placeholder ('blind text') content -- as raw markdown, for use as a starting point when drafting a new problem statement.
qa_exampleA complete, valid sample QA document as raw markdown -- frontmatter and body -- exercising every section, for use as a learning example.
qa_schemaThe generated QA JSON Schema (2020-12 dialect), generated by `specmgr schema` and kept current by a pre-commit hook/CI step. Includes a `$comment` schema-layout version marker for detecting a shape change without diffing the whole document.
qa_templateA QA document template -- frontmatter and every body field present, populated with short placeholder ('blind text') content -- as raw markdown, for use as a starting point when drafting a new QA document.
req_exampleA complete, valid sample requirement document as raw markdown -- frontmatter and body -- exercising every section, for use as a learning example.
req_schemaThe generated REQ JSON Schema (2020-12 dialect), generated by `specmgr schema` and kept current by a pre-commit hook/CI step. Includes a `$comment` schema-layout version marker for detecting a shape change without diffing the whole document.
req_templateA REQ document template -- frontmatter and every body field present, populated with short placeholder ('blind text') content -- as raw markdown, for use as a starting point when drafting a new requirement.
rsk_exampleA complete, valid sample risk document as raw markdown -- frontmatter and body -- exercising every section, for use as a learning example.
rsk_schemaThe generated RSK JSON Schema (2020-12 dialect), generated by `specmgr schema` and kept current by a pre-commit hook/CI step. Includes a `$comment` schema-layout version marker for detecting a shape change without diffing the whole document.
rsk_templateA risk document template -- frontmatter and every body field present, populated with short placeholder ('blind text') content -- as raw markdown, for use as a starting point when drafting a new risk.
rsk_risk_matrixThe 5x5 risk matrix: probability/impact scale anchors, the zone table, and the product thresholds (what 'high risk' and 'low risk' mean), as raw markdown domain-knowledge guidance.
rsk_taraWhat TARA is (Transfer, Accept, Reduce, Avoid), the four valid `## Strategy` words, and when and how to apply each, as raw markdown domain-knowledge guidance.
sop_exampleA complete, valid sample Standard Operating Procedure document as raw markdown -- frontmatter and body -- exercising every section, for use as a learning example.
sop_schemaThe generated SOP JSON Schema (2020-12 dialect), generated by `specmgr schema` and kept current by a pre-commit hook/CI step. Includes a `$comment` schema-layout version marker for detecting a shape change without diffing the whole document.
sop_templateA SOP document template -- frontmatter and every body field present, populated with short placeholder ('blind text') content -- as raw markdown, for use as a starting point when drafting a new Standard Operating Procedure.
sysrs_exampleA complete, valid sample System Requirements Specification document as raw markdown -- frontmatter and body -- exercising every section, for use as a learning example.
sysrs_schemaThe generated SYSRS JSON Schema (2020-12 dialect), generated by `specmgr schema` and kept current by a pre-commit hook/CI step. Includes a `$comment` schema-layout version marker for detecting a shape change without diffing the whole document.
sysrs_templateA SYSRS document template -- frontmatter and every body field present, populated with short placeholder ('blind text') content -- as raw markdown, for use as a starting point when drafting a new System Requirements Specification.
uc_exampleA complete, valid sample use case document as raw markdown -- frontmatter and body -- exercising every section, for use as a learning example.
uc_plantumlThe frozen UC → PlantUML mapping and validation rulebook (per-UC usecase and package diagram mapping, sequence-skeleton attribution and UNATTRIBUTED marker grammar, the strict 3-source validation chain, the jar/bin and URL invocation contracts, the two-mode structure checker, and user-owned platform-adapter snippets) as raw markdown domain-knowledge guidance.
uc_plantuml_exampleThe complete, fully attributed PlantUML sequence diagram for the packaged 'Buy Goods' example UC (every UNATTRIBUTED marker of the deterministic skeleton resolved by reasoned attribution, rulebook §2.9) as raw PlantUML source: not markdown, not a specmgr document (no frontmatter, not validate-able) -- text/plain. The model for the generate_uc_sequence_diagram prompt flow.
uc_plantuml_templateThe packaged PlantUML sequence-skeleton template (placeholder participants and mapping comments -- the shape get_uc_sequence_skeleton emits, rulebook §2.9) as raw PlantUML source: not markdown, not a specmgr document (no frontmatter, not validate-able) -- text/plain.
uc_schemaThe generated UC JSON Schema (2020-12 dialect), generated by `specmgr schema` and kept current by a pre-commit hook/CI step. Includes a `$comment` schema-layout version marker for detecting a shape change without diffing the whole document.
uc_templateA UC document template -- frontmatter and every body field present, populated with short placeholder ('blind text') content -- as raw markdown, for use as a starting point when drafting a new use case.
vcr_exampleA complete, valid sample verification case record document as raw markdown -- frontmatter and body -- exercising every section, for use as a learning example.
vcr_schemaThe generated VCR JSON Schema (2020-12 dialect), generated by `specmgr schema` and kept current by a pre-commit hook/CI step. Includes a `$comment` schema-layout version marker for detecting a shape change without diffing the whole document.
vcr_templateA VCR document template -- frontmatter and every body field present, populated with short placeholder ('blind text') content -- as raw markdown, for use as a starting point when drafting a new verification case record.
dec_exampleA complete, valid sample decision document as raw markdown -- frontmatter and body -- exercising every section, for use as a learning example.
dec_schemaThe generated DEC JSON Schema (2020-12 dialect), generated by `specmgr schema` and kept current by a pre-commit hook/CI step. Includes a `$comment` schema-layout version marker for detecting a shape change without diffing the whole document.
dec_templateA DEC document template -- frontmatter and every body field present, populated with short placeholder ('blind text') content -- as raw markdown, for use as a starting point when drafting a new decision.
configFor every document domain (adr, req, uc, tsk, qa, prb, gol, rsk, dec, sop, feat, vcr, sysrs), the resolved absolute base directory and whether the domain's SPECMGR_*_DIR environment variable is explicitly set, plus a static `similarity` section for the semantic-similarity feature (feat-134): whether the `similarity` extra (fastembed) is installed (a spec lookup, never an import), whether the presence-based SPECMGR_SIMILARITY_DISABLED opt-out flag is set, the fixed model name, and the resolved model cache directory (FASTEMBED_CACHE_PATH if set, else <tempdir>/fastembed_cache, reported but never created), plus whether the presence-based SPECMGR_FEAT_WARMUP_DISABLED opt-out flag is set (the unified startup warmup's feat frontmatter/full-parse phases, feat-187-list-feat-timeout), and a static `plantuml` section for the PlantUML validation source (feat-185-uc-diagrams Phase 120): the presence-only state of the exactly-three source env vars (SPECMGR_PLANTUML_JAR/SPECMGR_PLANTUML_BIN/SPECMGR_PLANTUML_URL, each {set: bool}, never a value) plus `selected` -- the first-set-wins selection over them ("jar"/"bin"/"url"/"none"), and a static `diagram` section for the reference-graph label limit (feat-207-reference-graph Phase 120, REQ-010): the presence-only state of SPECMGR_DIAGRAM_MAX_TITLE ({set: bool}, never a value), the helper's validity flag ({valid: bool}), the frozen default (40), and `resolved` -- a derived value, the effective label limit the get_reference_diagram/get_reference_diagram_all tools render with (40 when unset or set-but-invalid, the set int otherwise). Static configuration only -- the tools' own dynamic runtime availability is their structured {available, reason, message} result, not part of this resource. Never discloses the value of any environment variable except the resolved cache path, only whether the relevant directory-path/opt-out env vars are present.
dtaisWhat DTAIS is (Demonstration, Test, Analysis, Inspection, Special), the five valid `### AC-NNN (Method): ...` method words, and when and how to apply each, as raw markdown domain-knowledge guidance.
earsThe EARS (Easy Approach to Requirements Syntax) five requirement-phrasing templates (Ubiquitous requirements, Event-driven requirements, Unwanted behaviours, State-driven requirements, Optional features) and when to use each, as raw markdown domain-knowledge guidance.
iso25010The nine main characteristics (and their sub-characteristics) of the ISO/IEC 25010:2023 system/software product quality model, each with a description.
rasciWhat RASCI is (Responsible, Accountable, Support, Consulted, Informed), the five roles' standard definitions, and how RASCI differs from plain RACI, as raw markdown guidance.
reference_graphThe frozen reference-graph rulebook: the deterministic PlantUML component-diagram emission layout (the 14-entry palette, the bracketed alias/label/truncation rules, the title override + defaults, the FEAT-exclusion rule, the bare-`feat-NNN` source-id rejection with the `list_feat` discovery pointer, the SCC cycle rule + red-arrow syntax, the construction semantics, the CLI file layout) plus the pointer at the UC rulebook §3–§6 for the validation chain reused as-is — raw markdown domain-knowledge guidance.
versionInstalled version number of the biz-dfch-specmgr package that backs this MCP server, plus the installed fastembed package version (the similarity extra's embedding backend) or null when that extra is not installed (read via importlib.metadata, never an import of fastembed itself; feat-134 Phase 7). Lets a client check compatibility without a tool round-trip.

TDQS

B3.2/5.0

Scored across 103 tools

Disambiguation4/5

Tools follow a clear per-domain verb pattern (create_X/get_X/list_X) plus distinct cross-cutting verbs (update, edit, delete, validate, set_status), so purposes are mostly separable. The main friction is that get_X and parse_X overlap heavily (both read-and-parse a document from disk), and the sheer number of near-identical per-domain variants raises misselection risk.

Naming Consistency4/5

The dominant convention is consistent snake_case verb_noun (create_feat, get_feat, list_feat, find_related, validate_plantuml). Minor deviations exist in the ADR option verbs (option_create/option_read/option_update, noun-first) and the diagram readers (get_uc_diagram, get_use_case_package_diagram), but overall the pattern is predictable.

Tool Count1/5

103 tools is an extreme mismatch for a spec-management server. The count balloons because each of ~13 document domains gets its own near-identical set of create/get/list/parse/template/example tools, so the surface is a large, repetitive matrix rather than a well-scoped set.

Completeness4/5

Coverage is broad and deep: create/read/list/update/edit/delete/set_status/validate exist for nearly all whole-body domains, plus examples, templates, reference graphs, similarity search, and PlantUML tooling. Only minor gaps appear, e.g. delete/validate explicitly exclude ADR and rely on separate ADR-specific tools.

Maintenance

ActivityActive
ResponsivenessWithin a week