tei-mcp
This MCP server enables AI agents to read, write, and validate TEI P5 XML through schema grounding and span-locked composition tools.
Schema Grounding & Lookup
Look up TEI elements, classes, macros, and list all elements in a module, with case-insensitive matching and typo suggestions
Regex search across all TEI entities (elements, classes, macros, modules) by identifier, gloss, or description
Attribute Resolution
List all attributes for an element or class, including inherited attributes through the full class hierarchy
Show the full class membership chain; suggest attributes by plain-language intent description
Content Model & Nesting
Expand content models into structured JSON trees with class and macro resolution
List valid children of any element; check parent-child nesting validity (direct or recursive with path tracking); batch nesting checks
Document Validation
Validate full TEI XML documents against TEI P5: content models, attributes, closed value lists, reference integrity, deprecation warnings — accepts file path or raw XML string
Validate a single element in context for incremental editing workflows
ODD Customisation
Load a project ODD to constrain the schema (moduleRef filtering, elementSpec delete/change, attDef modifications); unload to revert to full TEI P5
Most tools accept
use_odd=Trueto query the customised schema
Span-Locked Composition
Retrieve immutable source plaintext; record TEI tags by specifying character offsets and element paths; assemble final TEI XML with a byte-equality body-text invariant that prevents the model from rewriting the source text; list and reset recorded tags
Deployment
Works as a local stdio server or remote HTTP server; document tools accept file paths or raw XML strings
Provides tools for interacting with and validating TEI (Text Encoding Initiative) XML documents, including element lookup, attribute resolution, content model expansion, and validation against the TEI P5 specification and ODD customizations.
tei-mcp
An MCP server that helps AI agents read and write valid TEI XML. It parses the TEI P5 specification and exposes 21 tools spanning two complementary capabilities: schema grounding (element lookup, attribute resolution, content model expansion, nesting validation, document validation, ODD customisation) and span-locked composition (annotation of source text without letting the model rewrite the body).
Features
Element, class, macro, and module lookup with case-insensitive matching and typo suggestions
Attribute resolution across the full TEI class hierarchy (local + inherited)
Content model expansion into structured trees with class and macro resolution
Nesting validation (direct parent-child and recursive reachability with path tracking)
Document validation against TEI P5: content models, attributes, closed value lists, reference integrity, deprecation warnings
Single-element validation for incremental editing workflows
ODD customisation support: load a project ODD to constrain the schema (moduleRef filtering, elementSpec delete/change, attDef modifications)
Regex search across all entity types (elements, classes, macros, modules)
Deprecation awareness with validUntil dates and replacement suggestions
Attribute suggestion by intent description (keyword matching against attribute descriptions)
Span-locked composition with a byte-equality body-text invariant: the model annotates source plaintext by registering tag offsets, and the composer assembles the final TEI without ever letting the model rewrite the body. See Span-Locked Composition below.
Local and remote usage: all tools work both when the server runs on your machine and when it runs on a remote server
Related MCP server: material-web-mcp
Requirements
Python 3.10+
uv (recommended) or pip
Installation
The quickest way is via uvx, which fetches and runs the server automatically:
uvx tei-mcpOr install from PyPI:
pip install tei-mcpOr clone and install from source:
git clone https://github.com/Pantagrueliste/tei-mcp.git
cd tei-mcp
uv syncOn first run, the server downloads p5subset.xml from the TEI website (~5 MB) and caches it locally.
Usage
Local server (stdio)
When you run tei-mcp on your own machine, it communicates over stdio. Add the following to your client's MCP server configuration:
{
"mcpServers": {
"tei": {
"command": "uvx",
"args": ["tei-mcp"]
}
}
}Where this file lives depends on your client:
Client | Configuration file |
Claude Desktop |
|
Claude Code |
|
Cursor |
|
Windsurf |
|
Other clients | Consult your client's MCP documentation |
Remote server (HTTP)
tei-mcp can also run as a remote HTTP server, so you don't need to install anything locally. Run it with:
fastmcp run tei_mcp/server.py:mcp --transport streamable-http --host 0.0.0.0 --port 8000Then point your MCP client at the server URL (e.g., http://your-server:8000/mcp).
When the server runs remotely, it cannot access files on your computer. Tools that work with documents (validate_document, load_customisation) accept the XML content directly as a string, so the AI agent can read your local file and send its content to the remote server. See Working with documents below.
Tools
Tool | Description |
| Look up an element by name (e.g., |
| Look up a class by name (e.g., |
| Look up a macro by name (e.g., |
| List all elements in a module (e.g., |
| Regex search across all TEI entities |
| Resolve all attributes for an element (local + inherited) |
| Show the full class hierarchy chain |
| Expand content model into a structured tree |
| List all valid direct children of an element |
| Check if an element can appear inside another |
| Check multiple nesting pairs in one call |
| Find relevant attributes by intent description |
| Validate a TEI XML document against the spec |
| Validate a single element in context |
| Load an ODD customisation |
| Clear the loaded customisation |
| Return source plaintext for a span-locked document |
| Record a TEI tag at a character range over the source |
| Assemble final TEI from recorded tags; enforces body-text byte-equality |
| List currently recorded tags for a document |
| Clear recorded tags for a document |
Most schema-grounding tools accept use_odd=True to query the customised schema instead of the full TEI P5. The span-locked tools (get_source, tag_span, compose, list_tags, reset_tags) require TEI_MCP_SPAN_SOURCE_ROOT to be configured (see Span-Locked Composition).
Working with documents
validate_document and load_customisation both need access to XML files. They support two ways of receiving them:
By file path (
file_path/odd_path): the server opens the file from disk. This is the simplest option when the server runs on your own machine.By content (
xml_content/odd_content): the XML is passed directly as a string. This is how remote servers work — the AI agent reads your local file and sends its content to the server.
You don't need to choose or configure anything. When you ask the AI agent to validate a document, it will automatically use the right approach depending on whether the server is local or remote.
Examples
Local server (file path):
validate_document(file_path="/path/to/my-document.xml")
load_customisation(odd_path="/path/to/my-project.odd")Remote server (content):
validate_document(xml_content="<TEI xmlns='...'>...</TEI>")
load_customisation(odd_content="<TEI xmlns='...'>...</TEI>")validate_document also supports authority files (for reference integrity checks) in both forms: authority_files for local paths, authority_contents for XML strings.
ODD Customisation
Load a project-specific ODD file to constrain the schema:
1. Call load_customisation(odd_path="/path/to/my-project.odd")
— or load_customisation(odd_content="<TEI>...</TEI>") for remote servers
2. Use use_odd=True on subsequent tool calls
3. Call unload_customisation() to revert to the full specSupported ODD features:
moduleRefwithinclude/exceptfilteringelementSpec mode="delete"to remove elementselementSpec mode="change"withattDefmodifications (delete, change, add)Closed/semi value list restrictions
Span-Locked Composition
A pattern for using language models to encode TEI without letting them rewrite the source.
In standard generation, a model is asked to produce TEI directly from a piece of source text. The model often produces output that looks correct but silently modifies the body — modernised spelling (mesme → même), dropped commas, archaic pronouns substituted (luy → lui), or wholly invented passages. Validators downstream cannot catch these errors: the output is well-formed and schema-valid, and only character-level diffing against the source surfaces the discrepancy. For archival workflows where the encoded text becomes a permanent record, this is the failure mode that matters most.
Span-locked composition prevents this by construction. The model never types body text. It retrieves the source through get_source, registers tags as offset ranges over that source through tag_span, and then asks the server to assemble the final TEI through compose. The composer interleaves the recorded tags with the source plaintext and verifies byte-by-byte that the rendered TEI's flat text content equals the source before returning. If the model's tags would yield a document whose body text differs from the source, compose() raises rather than returning a corrupted document.
This is complementary to schema grounding. The schema-grounding tools (validate_document, lookup_element, valid_children, etc.) help the model produce valid TEI; span-locked composition guarantees that the body text inside that TEI is faithful to the source. The two together cover both axes a deployable encoding workflow has to satisfy.
Configuration
Set TEI_MCP_SPAN_SOURCE_ROOT to a directory containing source plaintext files. Each file's stem becomes its document ID (e.g., letter_001.txt is addressed as letter_001). Source files are loaded lazily on first reference and cached for the lifetime of the server process.
export TEI_MCP_SPAN_SOURCE_ROOT=/path/to/sources
uvx tei-mcpWorkflow
Call
get_source("letter_001")to retrieve the immutable body text.Issue one or more
tag_span("letter_001", start, end, element_path, attrs)calls to register tags at character offsets.Call
compose("letter_001")to obtain the final TEI fragment, with the body-text byte-equality check enforced.Optionally call
list_tagsto inspect, orreset_tagsto start over.
element_path is a slash-separated path documenting nesting context (e.g. TEI/text/body/p/persName); only the last segment becomes the element's local name. The rest is recorded for provenance.
Limitations
Recorded tags are kept in process memory and do not survive server restart.
compose()does not currently check that the registered tags are admissible per the loaded ODD customisation. Validate the composed output withvalidate_documentas a separate step if schema validity matters for your workflow.Source files are read from disk at first reference, so the source-root directory must be readable at the time
get_sourceis invoked.
Environment Variables
Variable | Default | Description |
| — | Path to a local |
| TEI-C GitHub URL | Custom URL for the ODD file |
|
| Directory containing source plaintext files for span-locked composition. Files are addressed by filename stem. |
Development
# Install dev dependencies
uv sync
# Run tests
uv run pytest
# Run tests with coverage info
uv run pytest -vLicense
MIT
Available Tools
21 toolscheck_nestingA
Check whether a TEI element can appear inside another element.
By default checks direct parent-child validity. Set recursive=True to check if the child can appear anywhere nested inside the ancestor (with path tracking and cycle detection).
Direct mode returns: {valid, child, parent, reason} Recursive mode returns: {reachable, child, ancestor, path, reason}
The reason field explains why nesting is valid or invalid -- useful for understanding TEI structure and self-correcting markup. Set use_odd=True to query the customised schema.
Example: check_nesting("p", "div") Example: check_nesting("persName", "body", recursive=True)
| Name | Required | Description | Default |
|---|---|---|---|
| child | Yes | ||
| parent | Yes | ||
| recursive | No | ||
| use_odd | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description effectively discloses behavior: it describes two modes, return formats, path tracking, cycle detection, and the 'reason' field. It lacks mention of potential performance impacts or limits, but for a read-style check, this is sufficient.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is tightly written with no wasted words. It front-loads the core purpose, then adds mode details, return types, and examples efficiently. Every sentence serves a purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the moderate complexity and presence of an output schema, the description is complete. It covers both modes, custom schema usage, cycle detection, and the nature of the 'reason' field, leaving no significant gaps in understanding what the tool does and how to use it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Despite 0% schema description coverage, the description adds meaning by showing parameter roles through examples ('p', 'div' for child/parent) and explaining 'recursive' and 'use_odd'. It compensates well for the schema gaps, though a structured parameter list would be stronger.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it checks whether a TEI element can appear inside another, with specific verb and resource. It distinguishes between direct and recursive checks, but does not explicitly differentiate from the sibling 'check_nesting_batch', which limits clarity on when to use which.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains the two modes and gives examples, implying usage for understanding TEI structure. However, it does not explicitly state when to use this tool versus alternatives like 'validate_element' or 'valid_children', nor does it provide when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_nesting_batchA
Check multiple parent-child nesting relationships in a single call.
Each pair is a dict with 'child' and 'parent' keys. The recursive flag applies to all pairs (True = check reachability anywhere inside ancestor, False = check direct parent-child only).
Returns results for all pairs. If a pair has a typo, that pair gets an error with suggestions while other pairs still return valid results. Set use_odd=True to query the customised schema.
Example: check_nesting_batch([{"child": "p", "parent": "div"}, {"child": "head", "parent": "div"}])
| Name | Required | Description | Default |
|---|---|---|---|
| pairs | Yes | ||
| recursive | No | ||
| use_odd | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It details the pair structure, recursive flag behavior, error handling with suggestions for typos, and the use_odd parameter. It does not explicitly state that the tool is read-only, but that is typical for a 'check' operation. The behavioral context is well-covered.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is reasonably concise, with a clear front-loaded purpose. Each sentence contributes value, including an example. Minor reduction could be achieved without losing clarity, but overall it is well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool complexity and the presence of an output schema, the description is fairly complete. It covers parameter behavior, error handling, and includes an example. It does not describe the output format, but the output schema handles that. Slightly more detail on when 'use_odd' is needed would improve completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema coverage, the description fully explains all three parameters: 'pairs' as dicts with 'child' and 'parent' keys, 'recursive' applying to all pairs, and 'use_odd' for custom schema. This adds essential meaning beyond the schema definitions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool checks multiple parent-child nesting relationships in a single call. It uses a specific verb ('check') and resource ('nesting relationships'), and distinguishes itself from the sibling 'check_nesting' by being batch-oriented.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains when to use the tool: for multiple pairs in one call. It implies that for single pairs, the sibling 'check_nesting' should be used, but does not explicitly state when not to use this tool. The guidance is clear but lacks explicit exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
class_membership_chainA
Show the full class membership hierarchy for a TEI element or class.
Returns separate chains for each direct class membership. Each chain walks upward through the class hierarchy to the root. Each step includes the class ident, type (model or atts), and gloss.
Accepts both element names (e.g., "persName") and class names (e.g., "model.nameLike.agent"). Case-insensitive lookup with suggestions on not-found. Set use_odd=True to query the customised schema.
Example: class_membership_chain("persName")
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| use_odd | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Given no annotations, the description discloses behavior: returns chains with class ident, type, gloss; case-insensitive with suggestions on not-found; use_odd for custom schema. It lacks details on error handling but is sufficient.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, front-loaded with purpose, then details and an example. It could be slightly more structured but is efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 2 params, output schema exists, the description covers input types, optional flag, return format, and example. It is complete for a hierarchy query tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the description adds meaning: name accepts element or class names, case-insensitive with suggestions; use_odd explained. This compensates well for the schema gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it shows the full class membership hierarchy for a TEI element or class, specifying it returns separate chains walking upward. It distinguishes from siblings by focusing on hierarchy chains rather than single lookups.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage by listing accepted inputs and optional parameters, but does not explicitly specify when to use this tool versus alternatives like lookup_class or lookup_element.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
composeA
Emit final TEI by interleaving recorded tags with source text.
Body-text invariant: the rendered TEI's flat text content equals the source plaintext byte-for-byte by construction. compose() raises if the recorded tags would violate this invariant or contain crossings (which are invalid XML).
Args: document_id: Stable ID of the document. wrap_in_body: If True (default), wrap result as a fragment. If False, return tagged source text under a synthetic compose root (intended for sub-fragment composition).
Returns dict with 'document_id', 'tei' (string), and 'tag_count'.
| Name | Required | Description | Default |
|---|---|---|---|
| document_id | Yes | ||
| wrap_in_body | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses body-text invariant, error conditions (raises on violation or crossing), and return format. Annotations are absent, so description fully carries the burden and does so thoroughly.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Efficiently structured with clear paragraphs and bullet points. Essential details included without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers input, behavior, error conditions, output schema fields (document_id, tei, tag_count), and the wrap_in_body mode. No gaps given the tool's complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Documents both parameters beyond schema: document_id as 'stable ID', wrap_in_body explains default and behavior for True/False. Schema coverage was 0%, so description compensates fully.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states it 'emits final TEI by interleaving recorded tags with source text', a specific action on a defined resource. Distinguishes from siblings like tag_span or validate_document.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explains when wrap_in_body is used and the invariant condition, but does not explicitly compare to sibling tools or state when to use alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
expand_content_modelA
Expand the content model for a TEI element or macro into a structured tree.
Returns a nested JSON tree preserving structural semantics (sequence, alternation, repetition). Class references are resolved to concrete element names with 'via' annotations. Macro references are recursively resolved inline.
Accepts both element names (e.g., "div", "p") and macro names (e.g., "macro.paraContent"). Case-insensitive lookup with suggestions on not-found. Set use_odd=True to query the customised schema.
Example: expand_content_model("div")
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| use_odd | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description details behavioral traits: it returns a nested JSON tree, resolves class references with 'via' annotations, recursively resolves macro references, performs case-insensitive lookup with suggestions, and supports custom schema via use_odd. Given no annotations, this is a strong disclosure. It could explicitly state that the operation is read-only, but overall it's transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, with six sentences that follow a logical flow: purpose, output structure, resolution behavior, parameters, and an example. No redundant or extraneous information is present.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the tool's purpose, input parameters, output format, and special behaviors. Given that an output schema exists (per context signals), the description appropriately omits return value details. It could mention that the operation is read-only, but overall it is sufficiently complete for an AI agent to understand and invoke the tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 0% description coverage, so the description bears full responsibility. It explains that 'name' accepts element or macro names, provides examples ('div', 'p', 'macro.paraContent'), and mentions case-insensitivity. For 'use_odd', it explains that true queries the customised schema. This adds meaningful interpretation beyond the raw schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: expanding a TEI element or macro's content model into a structured tree. It specifies the verb ('Expand'), the resource ('content model'), and the output format ('nested JSON tree'). This distinguishes it from sibling tools that look up elements, macros, or validate documents.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains when to use the tool (for expanding content models of elements or macros, with optional custom schema querying via use_odd). However, it does not explicitly state when not to use it or provide alternatives from the sibling list, such as lookup_element or valid_children, which might be simpler for certain queries.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_sourceA
Return source plaintext for a span-locked document by stable ID.
The server reads the source from TEI_MCP_SPAN_SOURCE_ROOT/<id>.txt
(or any matching extension). Plaintext serves as the immutable body
text the model annotates over via tag_span; compose() reassembles
the final TEI by interleaving recorded tags with this source.
Args: document_id: Stable ID for the document. Filename stem with no extension; resolved against the configured source root.
Returns dict with 'document_id', 'length' (chars), and 'text'.
| Name | Required | Description | Default |
|---|---|---|---|
| document_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries burden. Discloses file path resolution and that text is immutable, but does not mention error cases, permissions, or side effects beyond what is implied.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is concise and well-structured with clear paragraphs and an Args section. Every sentence adds value with no fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity and the presence of an output schema, the description fully covers purpose, usage, parameter, and return values. It is complete enough for an AI agent to use correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The sole parameter document_id is thoroughly explained in the description: stable ID, no extension, resolved against root. This adds significant meaning beyond the schema, which had 0% description coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states it returns source plaintext for a span-locked document by stable ID, using specific verb and resource. It distinguishes from siblings like compose and tag_span by explaining the role of the returned text.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Description implies when to use this tool (before annotation via tag_span) and that compose reassembles final TEI, but does not explicitly state when not to use it or provide direct comparisons.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_attributesA
List all attributes for a TEI element or class, including inherited attributes.
Returns a flat list of attributes with local attributes first, then inherited in hierarchy order (nearest class first). Each attribute includes its name, source class (or "local"), datatype, allowed values, and whether the value list is closed. Local overrides of inherited attributes include an "overrides" field indicating which class was overridden.
Accepts both element names (e.g., "persName") and att.* class names (e.g., "att.global"). Case-insensitive lookup with suggestions on not-found. Set use_odd=True to query the customised schema.
Example: list_attributes("persName")
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| use_odd | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It comprehensively discloses the return structure (flat list, order, fields like source class, datatype, allowed values, closed flag, overrides), case-insensitivity, suggestions on not-found, and the use_odd flag for custom schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured in three paragraphs: purpose, return details, and input guidance with example. It is concise without unnecessary verbosity, though could slightly shorten the return description.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (inheritance, overrides, multiple input types) and the presence of an output schema, the description provides sufficient context. It misses edge cases like handling of invalid names but overall is thorough.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must add meaning. It explains that 'name' is a TEI element or class name (e.g., 'persName'), and 'use_odd' queries the customized schema. This adds significant value beyond the bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it lists all attributes for a TEI element or class, including inherited. It distinguishes from sibling tools like lookup_element or suggest_attribute by focusing on attribute listing with inheritance and override details.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains it accepts both element names and class names, provides an example, and mentions case-insensitive lookup with suggestions. While it doesn't explicitly say when not to use it, the context is clear enough for an AI agent to decide.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_module_elementsA
List all elements in a TEI module.
Returns the module's ident, gloss, and a list of {ident, gloss} pairs for each element. If module not found, returns an error with suggestions. Set use_odd=True to query the customised schema.
Example: list_module_elements("namesdates")
| Name | Required | Description | Default |
|---|---|---|---|
| module | Yes | ||
| use_odd | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It discloses the return format, mentions error handling, and implies a read-only operation (no side effects). It does not discuss rate limits or auth, but for a simple read tool this is adequate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is very concise: three sentences covering purpose, return data, error handling, and an example. Every sentence adds value with no fluff. Front-loaded with the main action.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simplicity of the tool, the description covers purpose, parameters, return structure, error handling, and an example. The presence of an output schema (not shown) means return details are fully covered. No gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema has 2 parameters with 0% description coverage in schema. The description adds value by explaining use_odd (query customised schema) and demonstrates module usage in an example, though it could provide more detail on allowed module values.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists all elements in a TEI module, specifying the return structure (ident, gloss, and element pairs). It is distinct from sibling tools like lookup_element or list_tags by focusing on module-level content.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides an example usage and notes error behavior (returns suggestions if module not found) and optional parameter use_odd for customized schema. However, it does not explicitly differentiate when to use this versus other listing tools, though the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_tagsA
List all tags currently recorded for a span-locked document.
Returns dict with 'document_id', 'tag_count', 'tags' (list of dicts).
| Name | Required | Description | Default |
|---|---|---|---|
| document_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It reveals the return structure (dict with document_id, tag_count, tags), which is helpful, but does not explicitly state that the operation is read-only or disclose any side effects. Adequate but could be clearer.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, with two sentences that efficiently convey the purpose and return format. No extraneous information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the single parameter and presence of an output schema, the description provides adequate context: what the tool does and what it returns. However, it does not explain the 'span-locked' requirement or what happens if the precondition is not met, leaving minor gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The only parameter 'document_id' is defined in the schema but has no description. The tool description mentions 'span-locked document' but does not elaborate on what document_id is or how to obtain it. With 0% schema coverage, the description fails to add sufficient meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: listing all tags for a span-locked document. It uses a specific verb ('List') and resource ('tags'), and distinguishes from sibling tools like 'reset_tags' and 'tag_span' by specifying the context.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives, nor are there any notes on prerequisites or exclusions. The description simply states what it does without contextual usage advice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
load_customisationA
Load a project ODD customisation to constrain validation.
Provide either odd_path (a local file path) or odd_content (the raw XML string of the ODD file). When using a remote server, pass odd_content directly since the server cannot access your local filesystem.
Parses the ODD and creates a constrained OddStore. Returns element count comparison (customised vs base). Set use_odd=True on other tools to query the customised schema.
| Name | Required | Description | Default |
|---|---|---|---|
| odd_path | No | ||
| odd_content | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description discloses key behaviors: parsing ODD, creating a constrained OddStore, returning element count comparison, and remote server limitation. Lacks details on idempotency or state overwrite.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Five concise sentences, front-loaded with purpose, logically structured: purpose, parameter details, remote note, behavior/return value, follow-up usage. No redundant words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers purpose, parameters, remote limitation, return value, and integration hint. Could mention error conditions (e.g., invalid file path) but overall adequate given output schema existence.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema has 0% coverage; description adds semantic meaning: odd_path is a local file path, odd_content is raw XML string. Also explains when to use each, compensating for schema gaps.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool loads a project ODD customisation to constrain validation, with a specific verb ('load') and resource ('customisation'). It distinguishes from siblings like 'unload_customisation'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit guidance on choosing between odd_path and odd_content based on local vs remote usage, and advises setting use_odd=True on other tools. But does not contrast with alternatives like unload_customisation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lookup_classA
Look up a TEI class by name (case-insensitive).
Returns the class's ident, module, class_type, gloss, desc, classes, attributes, and a computed members list of element/subclass idents. If not found, returns an error with suggestions. Set use_odd=True to query the customised schema.
Example: lookup_class("att.global")
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| use_odd | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses case-insensitivity, error handling with suggestions, and the effect of use_odd. Lists return fields comprehensively. No annotations, so description carries full burden; it adequately covers key behaviors but omits potential side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Five concise sentences including a useful example. Front-loaded with main purpose. Every sentence adds value without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no annotations and low schema coverage, description is thorough: explains purpose, parameters, return fields, error behavior, and customization. Output schema exists, so return format detail is not needed. Minor gaps in computation of members list, but overall sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema coverage, description fully explains both parameters: name is case-insensitive, use_odd enables custom schema queries. Adds meaning beyond type/default.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states it looks up a TEI class by name with case-insensitivity. Lists specific return fields and includes an example, distinguishing it from sibling tools like lookup_element and lookup_macro.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Implicitly guides when to use: for class lookups, not elements or macros. Mentions error behavior with suggestions and use_odd parameter for custom schema, but lacks explicit exclusions or alternative tool references.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lookup_elementA
Look up a TEI element by name (case-insensitive).
Returns the element's ident, module, gloss, desc, classes, attributes, and content_raw. If not found, returns an error with suggestions. Set use_odd=True to query the customised schema.
Example: lookup_element("persName")
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| use_odd | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must disclose behavior. It states the lookup is case-insensitive, lists the return fields, explains error handling with suggestions, and describes the use_odd parameter. However, it does not explicitly state that the tool is read-only or has no side effects, though that is implied. For a lookup tool, this is reasonably transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise: three informative sentences plus an example. It front-loads the purpose, then details output, error handling, and the optional parameter. Every sentence adds value without redundancy. The example concretely demonstrates usage.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the context signals that an output schema exists (though not provided), the description does not need to detail return structures. It already lists the returned fields (ident, module, gloss, etc.) and mentions error handling. For a simple lookup tool, this covers what an agent needs to invoke it correctly and interpret results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 2 parameters with 0% description coverage. The description adds semantics: it explains that name is case-insensitive (not in schema) and that use_odd queries the customised schema. This provides clear meaning beyond the bare schema. However, the description could elaborate on what constitutes a valid TEI element name, but the example partially addresses this.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Look up a TEI element by name (case-insensitive).' It specifies the action (look up) and the resource (TEI element). Among siblings, there are other lookup tools like lookup_class and lookup_macro, and this description effectively distinguishes itself by focusing on elements, which is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides context like error handling with suggestions and an optional parameter use_odd for customised schema, but it does not explicitly guide when to use this tool over siblings like lookup_class or lookup_macro. While the example illustrates usage, the lack of explicit alternative guidance means the agent must infer scope from name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lookup_macroA
Look up a TEI macro by name (case-insensitive).
Returns the macro's ident, module, gloss, desc, and content_raw. If not found, returns an error with suggestions. Set use_odd=True to query the customised schema.
Example: lookup_macro("macro.paraContent")
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| use_odd | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description bears full responsibility for behavioral disclosure. It conveys that the tool is a read operation, returns specific fields, and handles missing names with suggestions. This is sufficient for a simple lookup tool, though it does not explicitly state it is read-only or mention any authorization needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise: three sentences plus an example line. It front-loads the main purpose and efficiently covers key details (case-insensitivity, return fields, error handling, optional parameter). No redundant information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is a simple lookup, and an output schema exists, reducing the burden on the description. It covers core functionality, error behavior, and the optional parameter. It does not explain the output schema details (justified by its existence) but could mention its read-only nature for completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 0% description coverage, so the description must add meaning. It explains 'use_odd=True to query the customised schema' and provides an example for 'name'. However, it does not describe the naming convention for macros beyond the example, leaving some ambiguity.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Look up a TEI macro by name', specifying the action and resource. It is case-insensitive and returns specific fields. However, it does not explicitly distinguish from sibling tools like lookup_class or lookup_element, which have similar names and purposes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides an example and notes that errors with suggestions are returned if not found. It explains when to use use_odd=True for customised schemas. However, it does not give guidance on when to use this tool instead of other lookup tools (e.g., for elements or classes).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
reset_tagsA
Clear all recorded tags for a span-locked document.
The source text is preserved; only the in-memory tag list is cleared. Useful for retry / fresh-start workflows during a single session.
| Name | Required | Description | Default |
|---|---|---|---|
| document_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description explains that source text is preserved and only the in-memory tag list is cleared, which is transparent about effects. No annotations are present, so the description carries the burden adequately.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three concise sentences with no wasted words or redundant information; front-loaded with the core action.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with one parameter and an output schema, the description covers the main behavior and use case, though it omits details on error handling or return values.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The only parameter, document_id, is not described in the description nor in the schema (coverage 0%). The description does not add meaning beyond the parameter name, leaving the agent guessing about format or constraints.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool resets tags for a span-locked document, distinguishing it from sibling tools like list_tags and tag_span.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It mentions usefulness for retry/fresh-start workflows, providing a clear usage context, but does not explicitly exclude other scenarios or offer alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
searchA
Search TEI entities by regex pattern across ident, gloss, and desc.
Each result includes type, ident, gloss, and match_field (which field matched). Optionally filter by entity_type and limit results. Set use_odd=True to query the customised schema.
Example: search("pers.*Name")
| Name | Required | Description | Default |
|---|---|---|---|
| pattern | Yes | ||
| entity_type | No | ||
| max_results | No | ||
| use_odd | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description must self-disclose. It mentions the search is read-only (by nature) and what fields are returned, but lacks details on auth, rate limits, or side effects. Adequate but not exhaustive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences plus an example, front-loaded with purpose, no redundant or missing words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Output schema exists, so return value explanation is optional but included. Covers parameter usage and filtering. Could mention default behavior (e.g., max_results=50) but mostly complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema has 0% description coverage; description compensates by explaining all four parameters: pattern (regex), entity_type (filter), max_results (limit), use_odd (custom schema). Provides example but no regex dialect details.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description states 'Search TEI entities by regex pattern across ident, gloss, and desc' – a specific verb and resource with clear scope, distinguishing it from sibling tools like lookup_element.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides context for optional filtering (entity_type, max_results, use_odd) and an example, but does not explicitly tell when to use this tool versus alternatives like lookup_class or validate_document.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
suggest_attributeA
Find the most relevant attributes for an element by describing what you want.
Searches attribute descriptions for keyword matches against your intent. Returns the top 5 matching attributes with name, description, source class, and relevance score. Set use_odd=True to query the customised schema.
Example: suggest_attribute("persName", "link to authority")
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| intent | Yes | ||
| use_odd | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Describes return format (top 5 matches with details) and the 'use_odd' parameter, but omits behavioral details like default behavior, edge cases, or whether it's read-only. Since no annotations exist, the description partially but not fully carries the burden.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is concise (a few sentences plus example), front-loaded with core purpose, and avoids redundant details. Example adds value without extra bloat.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a search tool with output schema, the description adequately explains what is returned. Slight lack of specificity about the matching algorithm, but overall sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although schema has zero description coverage, the description adds meaning for all three parameters: 'name' is the element, 'intent' is the desired description, and 'use_odd' customizes the schema. This compensates well for the missing schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool finds relevant attributes by describing intent, which distinguishes it from sibling tools like 'list_attributes' that simply list all attributes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives; lacks explicit when-to-use or when-not-to-use context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tag_spanA
Record a TEI tag spanning [start, end) in a span-locked document.
The model emits tags as offset+element tuples over the source plaintext. Tags are stored per document until compose() is invoked; the source text itself is never modified.
Args: document_id: Stable ID of the document (must have been registered via get_source first or be reachable by source_root). start: Inclusive char offset (0-based) in the source text. end: Exclusive char offset (start <= end <= len(source)). element_path: Slash-separated path documenting nesting context. Only the LAST segment becomes the element's local name. E.g. "TEI/text/body/p/persName" → . attrs: Optional dict of attribute name → value. xml:* attrs are supported via the "xml:..." key prefix.
Returns the recorded tag dict, or an error dict on validation failure.
| Name | Required | Description | Default |
|---|---|---|---|
| document_id | Yes | ||
| start | Yes | ||
| end | Yes | ||
| element_path | Yes | ||
| attrs | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description fully carries the burden. It states that 'the source text itself is never modified' (non-destructive), explains the return value ('Returns the recorded tag dict, or an error dict'), and outlines the storage behavior. It does not cover authentication or rate limits, but these are not expected for this tool context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a leading sentence, a brief context paragraph, and a clear parameter list. It is moderately long but each sentence serves a purpose. Minor redundancy in the args section (e.g., repeating types from schema) but adds clarity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (5 parameters, one nested object) and the presence of an output schema, the description provides all necessary information: purpose, usage context, parameter semantics, return behavior, and error handling. It is complete for an AI agent to select and invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Since schema description coverage is 0%, the description must compensate, and it does thoroughly. Each parameter is explained with specific details: start (0-based inclusive), end (exclusive, bounds), element_path (last segment becomes local name, with example), attrs (optional, supports xml: prefix).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description starts with a clear verb+resource: 'Record a TEI tag spanning [start, end) in a span-locked document.' It distinguishes this tool from siblings (like compose, validate_document, etc.) by focusing on the action of recording a tag, which is not done by other listed tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains the context: 'Tags are stored per document until compose() is invoked.' This implies when to use the tool (before composing) and places it in a workflow. However, it does not explicitly state when not to use it or suggest alternatives, though the sibling context provides some implicit guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unload_customisationA
Clear the loaded ODD customisation.
After unloading, all tools return to using the full TEI P5 spec. Calling a tool with use_odd=True after unloading will return an error.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Despite no annotations, the description discloses the mutation (clearing) and its irreversible behavioral effect: tools revert to full spec and use_odd=True will error. This covers the essential behavioral traits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the main action, no redundant words. Perfectly concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers purpose, behavior, and consequences. Has output schema, so no need to describe returns. Complete for a parameterless tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema has zero parameters and 100% schema coverage. The description adds no parameter info, which is acceptable because there are no parameters. Baseline for 0 params is 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states 'Clear the loaded ODD customisation' and differentiates from sibling tools like load_customisation by explaining that after unloading, all tools return to using the full TEI P5 spec.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states the consequence (tools revert to full P5 spec) and warns about calling a tool with use_odd=True after unloading, providing clear when-to-use and when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
validate_documentA
Validate a TEI XML document against the TEI P5 specification.
Checks content model compliance, attribute validity, closed value lists, empty required-content elements, reference integrity, and deprecation usage. Set use_odd=True to query the customised schema.
Provide either file_path (a local file path) or xml_content (the raw XML string). When using a remote server, pass xml_content directly since the server cannot access your local filesystem.
Authority files can likewise be provided as local file paths (authority_files) or as raw XML strings (authority_contents).
Returns a dict with 'issues' (list of validation issues), 'summary' (counts by severity and rule), and 'limitations' (what was NOT checked).
| Name | Required | Description | Default |
|---|---|---|---|
| file_path | No | ||
| xml_content | No | ||
| authority_files | No | ||
| authority_contents | No | ||
| use_odd | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so the description fully discloses behavior: it performs validation checks, returns issues/summary/limitations, and notes that remote servers cannot access local filesystems. It does not mention read-only nature but that is implied by validation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a clear opening, bullet-like list of checks, and parameter usage instructions. It is relatively concise for the complexity, though slight redundancy could be trimmed.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 5 parameters, no required ones, and an output schema (though not shown), the description covers all aspects: what the tool does, parameter options, behavioral notes, and return structure. It is complete for an agent to use correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema has 0% description coverage, but the description thoroughly explains the purpose and usage of each parameter: file_path/xml_content mutual exclusivity, authority_files/authority_contents, and use_odd. This adds significant meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it validates a TEI XML document against TEI P5 specification and lists specific checks (content model, attribute validity, etc.). It distinguishes from sibling tools like validate_element by indicating this validates entire documents.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear guidance on when to use file_path vs xml_content and mentions use_odd for custom schema. It does not explicitly say when not to use this tool, but the context is clear and it differentiates from siblings implicitly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
validate_elementA
Validate a single TEI element in context for incremental editing.
Accepts a raw XML snippet (e.g., 'text') or a JSON-formatted string with keys 'name', 'attributes', 'children'. Set use_odd=True to query the customised schema.
Args: element: XML snippet string or JSON string with element details. parent: The parent element name (required for nesting validation).
Returns a dict with 'issues', 'summary', and 'limitations'.
| Name | Required | Description | Default |
|---|---|---|---|
| element | Yes | ||
| parent | Yes | ||
| use_odd | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the burden of behavioral disclosure. It explains the two input formats, the role of the 'use_odd' parameter, and the return structure (dict with 'issues', 'summary', 'limitations'). It does not explicitly state that the tool is read-only or non-destructive, but given the validation nature, this is implied. The description is fairly transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, using only four sentences plus an Args listing. It front-loads the purpose, then covers input formats and key parameters. Every sentence adds value with no repetition or fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the tool's purpose, input formats, parameters, and return structure. Given that an output schema exists (as per context, though not shown), the description provides sufficient context for an agent to understand usage. It is complete for a tool with three parameters.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must explain parameters. It does so effectively: element is described as 'XML snippet string or JSON string with element details' with an example, parent is 'The parent element name (required for nesting validation)', and use_odd is 'Set use_odd=True to query the customised schema.' This adds significant meaning beyond the schema's type information.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Validate a single TEI element in context for incremental editing.' It specifies the verb (validate), resource (TEI element), and context (incremental editing), which distinguishes it from sibling tools like 'validate_document' (whole document) and 'check_nesting' (nesting only).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description indicates the tool is for incremental editing, suggesting when to use it. It provides an example of input formats, but does not explicitly state when not to use it or mention alternative tools. The context of siblings is available, but no direct guidance is given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
valid_childrenA
List all elements that can appear as direct children of the given element.
Returns a flat, deduplicated list of child element names with required/optional flags. Also indicates whether the element allows text content, any element, or has an empty content model. Set use_odd=True to query the customised schema.
Example: valid_children("div")
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| use_odd | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully discloses behavior: returns a list with required/optional flags, text/any/empty content indication, and the customised schema option. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is brief, front-loaded with purpose, includes an example, and every sentence is necessary. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given an output schema exists (not shown), the description need not detail return values. It covers the main purpose, parameters, and example adequately for a simple tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Despite zero schema description coverage, the description adds meaning for both parameters: 'name' implied as the element, and 'use_odd' explicitly explained. The example further clarifies usage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists direct children of an element, specifies the output format (flat deduplicated list with flags), and distinguishes it from siblings like check_nesting and expand_content_model.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explains when to use (to list children) and provides a usage hint for the customised schema (use_odd=True). Does not explicitly exclude alternatives, but the context is clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
5 tool updates
v0.3.0- Added
compose - Added
get_source - Added
list_tags - Added
reset_tags - Added
tag_span
16 tool updates
v0.2.0- First observed
check_nesting - First observed
check_nesting_batch - First observed
class_membership_chain - First observed
expand_content_model - First observed
list_attributes - First observed
list_module_elements - First observed
load_customisation - First observed
lookup_class - First observed
lookup_element - First observed
lookup_macro - First observed
search - First observed
suggest_attribute - First observed
unload_customisation - First observed
valid_children - First observed
validate_document - First observed
validate_element
TDQS
Scored across 21 tools
Most tools are clearly distinct: get_source/tag_span/compose/reset_tags form a workflow, while lookup_* and check_* tools are separate. However, check_nesting and check_nesting_batch overlap heavily, differing only by batch and recursive parameter; agents may confuse when to use which, though descriptions clarify the batch variant.
Tool names follow a consistent verb_noun pattern (lookup_*, validate_*, check_*, list_*, get_*, tag_span, compose). Minor deviations like tag_span and compose use a verb_noun form but without underscore between verb and noun (camelCase), but this is a small stylistic inconsistency and does not break predictability.
With 21 tools, the server is substantial but well-scoped for the domain of TEI XML validation, lookup, and span-locked annotation. Each tool serves a distinct function in the workflow (schema querying, validation, customisation, span annotation), and the count is justified without being bloated.
The server covers schema lookup (element, class, macro), validation (document, element, nesting, batch), customisation (load/unload ODD), and annotation workflow (get_source, tag_span, list_tags, reset_tags, compose). Missing are operations like updating or deleting a tag, but the span-locked design makes that intentionally immutable; also no tool to list all elements of a class (though lookup_class gives members), which is a minor gap.
Maintenance
Related MCP Connectors
Validate EU, UK, AU VAT numbers for AI agents. EU ViDA e-invoicing compliance.
Preflight QA for AI-agent deliverables with structured verdicts and repair guidance.
49 deterministic tools for text integrity, agent control, and contextual quality evidence.
Utility tools for AI agents: hashing, text stats, validation, DNS, currency, GEO audits.
Related MCP Servers
- FlicenseNot gradedqualityCmaintenanceEnables AI agents to diagnose, modify, and validate OTF/TTF fonts interactively through a set of read-only, write, and validation tools.-
- AlicenseAqualityCmaintenanceProvides programmatic access to Material Web documentation and components for AI agents, enabling documentation search, template generation, and HTML validation.711 npm1MIT
- AlicenseAqualityBmaintenanceValidates EU electronic invoices (Peppol, XRechnung, FatturaPA, etc.) and explains validation error codes, enabling AI coding agents to check invoice validity and get fixes before rejection.325 npmMIT
- AlicenseBqualityBmaintenanceEnables AI agents to author, validate, and build ICC Plus interactive fiction projects with full schema awareness and source-backed indexing.271MIT