ticket-ai
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@ticket-aicheck this draft ticket against our house style"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
ticket-ai
An MCP server and CLI that measures how your team actually writes tickets, and holds new ones to that. Not this ticket is bad — 31 of the 40 tickets that shipped here have an acceptance-criteria section, and this one does not.
No 'Akzeptanzkriterien' section. 31 of the 40 exemplar tickets (78%) have one.
Most ticket advice is free and therefore ignored. "Add acceptance criteria", "include steps to reproduce" — everyone has heard it, nobody changed anything. A count of what already happened in your own project is harder to wave away, and it is not an opinion about tickets.
There is no model in the loop for any of that. Learning the house style, finding related tickets and measuring a draft are counting, and run with no key and no network beyond your tracker. Writing a ticket needs a model, so that part is opt-in and which one is your choice. What it found when it was run against real boards →
Install
uv tool install ticket-ai-mcpConfiguration is environment variables only — a token passed as --token ends
up in your shell history and in the process list.
export TICKET_AI_TRACKER=gitlab
export TICKET_AI_PROJECT=acme/shop # or the numeric id
export TICKET_AI_GITLAB_URL=https://gitlab.example.com
export TICKET_AI_GITLAB_TOKEN=... # read_api scope is enoughThe token is optional on a public project. TICKET_AI_GITLAB_URL=https://gitlab.com
with no token reads any public board, which is the quickest way to see what
this does before pointing it at your own instance.
# Jira — Cloud or self-hosted Server / Data Center. Which one you are on is
# detected from the instance; you do not have to say.
export TICKET_AI_TRACKER=jira
export TICKET_AI_PROJECT=PROJ
export TICKET_AI_JIRA_URL=https://acme.atlassian.net
# Leave the credentials unset for a public board — plenty answer without any.
# Cloud: the token comes from id.atlassian.com, and is not the password.
export TICKET_AI_JIRA_EMAIL=you@example.com
export TICKET_AI_JIRA_TOKEN=...
# Self-hosted: a personal access token on its own, sent as a Bearer.
export TICKET_AI_JIRA_TOKEN=...
# Only if detection gets it wrong: cloud | server | auto (the default)
export TICKET_AI_JIRA_API=server
# GitHub
export TICKET_AI_TRACKER=github
export TICKET_AI_PROJECT=acme/shop
export TICKET_AI_GITHUB_TOKEN=...Related MCP server: pr-narrator-mcp
One command
ticket-ai learn # mine the tracker, cache the profile
ticket-ai style # what it learnedlearn takes a minute or two: ranking needs each ticket's comments and linked
merge requests, which is an extra request or two per ticket. It caches to
TICKET_AI_CACHE_DIR if you set one and to .ticket-ai/ otherwise, so it
happens once rather than once per review.
Then the rest:
ticket-ai learn --from '#412,#98' # or name the good ones yourself
ticket-ai context 'export is broken on mobile' # what already exists
ticket-ai gaps # declared template vs what arrives
ticket-ai draft --title '...' --file draft.md # check one before creating it
ticket-ai review '#42' # measure one that exists
ticket-ai open # every open ticket, worst firstdraft is the one worth building a habit around. Checking a ticket after you
create it puts the review past the point of no return: the board has already
been notified and every fix is now an edit with a history.
$ ticket-ai draft --title 'Filter kaputt' --file draft.md
Alignment with house style: 33% over 3 checks
### MEDIUM - The description is 116 characters.
The shortest quarter of tickets that shipped here start at 639; the median is 1079.
### MEDIUM - The ticket has no labels.
62% of the exemplars are labelled.--from is taken as given: no filtering, no scoring against your choices. Name
a ticket with a three-word description and that is your answer about how this
team writes tickets, and the profile will say so.
As an MCP server
{
"mcpServers": {
"ticket-ai": {
"command": "uvx",
"args": ["ticket-ai-mcp"],
"env": {
"TICKET_AI_TRACKER": "gitlab",
"TICKET_AI_PROJECT": "acme/shop",
"TICKET_AI_GITLAB_URL": "https://gitlab.example.com",
"TICKET_AI_GITLAB_TOKEN": "..."
}
}
}
}Eight tools, all read-only: learn_conventions, house_style,
ticket_template, ticket_context, template_gaps, review_draft,
review_ticket, review_open_tickets.
Add TICKET_AI_REPO to the env block if the checkout you want searched is
not the assistant's working directory.
Writing a ticket this way
The path to reach for if you already use Claude Code: no key, no compose, no
second model call. Ask for a ticket and the assistant does five things, three
of them here:
ticket_template— the shape: which sections, how long, what language, which labels.ticket_context— what exists: related tickets, the files their merge requests changed, the files in the checkout that mention it.It reads those files.
ticket_contextruns a text search, not an analysis; it says where to look, it does not save you looking.It writes the ticket.
review_draft— measures what it wrote, and fixes what that finds before showing you anything.
Where the "AI" is
Counting cannot produce a paragraph of German, so writing a ticket needs a model. Everything else needs nothing.
Writes | Needs | |
MCP, in Claude Code | yes | nothing — the assistant is already a model |
| yes | a model on your machine. No key, no account, nothing leaves the laptop |
| yes | a base URL and a key. OpenRouter, Azure AI Foundry, vLLM, any provider |
no writer (default) | no | nothing. Measures and gathers; you write |
export TICKET_AI_WRITER=ollama # or openai, with a base url and key
ticket-ai models # what that endpoint can reach
ticket-ai compose --title 'Etikettendruck bricht bei mehr als zehn Positionen ab'
ticket-ai models --workflow # an Actions workflow that drafts new issuescompose writes the body, measures it, hands the findings back to the model
once, and prints the review to stderr so the body alone can be redirected.
--fail-under makes it refuse to emit a draft that missed the house style.
Whichever model writes, the draft goes through the same measurement as any other ticket. That loop is why a small local model is usable here: it writes into a shape worked out by counting, and is marked against your team's own tickets afterwards.
A page instead
ticket-ai ui --lang de # or enA local page on 127.0.0.1:8760 with three tabs: the house style, a box to
paste a draft into, and the open backlog worst-first. Loopback only, because
this process holds a tracker token, and there is no flag to change that.
No build step and no CDN — one HTML file with its CSS and JavaScript inline.
Two languages, and they are separate
export TICKET_AI_UI_LANGUAGE=de # buttons and headings
export TICKET_AI_TICKET_LANGUAGE=de # what it says to write tickets inThe distinction is easy to collapse and worth keeping. A German team may want the tool's own buttons in English; someone joining a German board still has to write the ticket in German.
TICKET_AI_TICKET_LANGUAGE overrides what the corpus measured and takes effect
without re-learning. Leave it unset unless the board is mid-switch — a
measurement beats a setting, and forcing a language the board does not use
makes every existing ticket fail the language check.
Findings, the caveats under them and the list of what a ticket already got right are all rendered in the reader's language at the moment they are shown. The section names inside them are not: those are the team's own headings, and translating one turns it into a section the team does not have.
In CI
ticket-ai review "$CI_ISSUE" --fail-under 0.5What it measures
The house style. Sections, length, labels, title markers, language — over a corpus it either took from you or found itself. Every finding cites a count over that corpus.
The tickets that failed, not only the ones that worked. A rate can be a comparison: not "78% of tickets have acceptance criteria" but "78% of the ones that shipped, and 30% of the ones that stalled". The second is evidence; the first invites a shrug.
The split is on outcome alone — a merged change, a reopen, a run of clarifying questions — and never on what the ticket contains, because splitting on content and then comparing content would be circular. Tickets a staleness bot closed are left out of both groups: those say something about attention rather than about writing. On a board where nothing separates the two, it says so, which is worth knowing before anyone is asked to write differently. docs/shipped-against-stalled.md has the guards and the real board that forced the bot exclusion.
Sections that only travel together. A section carried by 41% of tickets is under any threshold worth having — but if it is on 76% of the tickets that also have a Ziel section and 20% of the ones that do not, the team has a template and applies it to one kind of work. A board-wide rate hides that entirely.
The form you declared, against the tickets you got. With a
.github/ISSUE_TEMPLATE or .gitlab/issue_templates in the checkout, gaps
lines each field up against how often tickets actually carry it — and the gap
runs both ways. A required field that turns up in 10% of tickets is a form
asking for something people cannot easily give. A section most tickets carry
that no form mentions is a convention the project grew and never wrote down.
What you need to write one. Give it a subject and it returns the related past tickets, the files the merge requests for those tickets actually changed, and the files in your checkout that mention it. That middle one lives only in the tracker's history — no amount of reading the code produces it, and it is usually the fastest way to find where the work will land.
How the mining works
Only closed tickets are sampled: an open ticket may be beautifully written, but nothing about it yet shows anyone could act on it. Each is scored on
Signal | Weight | Why |
A merged MR is attached | 0.30 | Strongest evidence someone could build it as written |
Substantial description | 0.20 | A stub teaches nothing about a template |
Has sections | 0.15 | The template is the thing being learned |
No clarifying questions | 0.15 | Eleven "what do you mean?" comments means it was not clear |
Never reopened | 0.10 | Reopened means closed before it was understood |
Labelled | 0.10 |
Tickets opened and closed inside an hour are halved — usually duplicates or typo fixes, whose shape is not the shape of real work. Bot authors are dropped outright; learning a house style from Renovate is a real failure mode. No one author may supply more than 40% of the corpus, or the profile describes your most prolific ticket-writer instead of your team.
Every score carries the reasons that produced it. A corpus you cannot argue with is one you will not trust.
What it will not tell you
Whether your tickets are any good. Nothing here reads for meaning; it counts. It cannot tell you whether your acceptance criteria make sense. It can tell you that the 40 tickets that shipped in this project all had some and this one does not.
Alignment is not quality. The score is distance from the tickets that historically got built here. A one-line ticket from someone who knows exactly what they mean can score badly and be completely fine. The tool says this about itself, and so should you when you quote it at a colleague.
Nothing about your tracker's contents changes. Every operation is a read.
The ranking signals are also circumstantial. A well-written ticket closed as out-of-scope with no MR scores badly, and that is an acceptable error: the goal is thirty representative tickets, not the thirty best ones. A thin sample says so, loudly, in the report and in every review built on it.
Jira has no public API for linked branches and merge requests, so the "shipped" signal there falls back to remote links, and a board that does not post them cannot be split into shipped and stalled at all. It says that rather than reporting every ticket as stalled. That is a limit of the API, not of the corpus.
Documentation
What running it against forty-three real boards, an MCP client, a browser and a clean install found. Almost all of it had full line coverage at the time | |
Five tickets it wrote, unedited, with the score each one got | |
How the two groups are split, and the guards that keep the comparison honest | |
Running the writer on a 2 GB local model: measured timings, and what it trades away |
Verified against
Run end to end, read-only, against home-assistant/core, pydantic/pydantic,
astral-sh/uv, fastapi/fastapi (GitHub), inkscape/inkscape and
gitlab-org/gitlab-runner (GitLab), hibernate.atlassian.net HHH (Jira Cloud),
issues.apache.org/jira KAFKA (Jira Data Center), and one private GitLab board.
Home Assistant produces no conditional rules at all, which is the right answer: their issue form is mandatory, so every section already clears the board-wide threshold and a conditional has nothing to add.
Development
uv sync
uv run pytest
uv run ruff check .
bash install_check.sh # build the wheel and drive it from a clean venv
uv run python tests/fleet.py # the whole tool across 43 public boardsLicense
MIT.
Available Tools
8 toolshouse_styleARead-only
What this team's tickets look like: template, length, labels, habits.
Reads the cached profile. Says so plainly if none has been learned yet rather than returning something empty that looks like an answer.
| Name | Required | Description | Default |
|---|---|---|---|
| project | No | ||
| tracker | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark it readOnlyHint/openWorldHint/destructiveHint false; the description adds that it reads a cached profile and, importantly, will explicitly say when no profile exists instead of returning misleading empty data. That is meaningful behavioral context beyond annotations.
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 short, front-loaded sentences: the first states the resource and content, the second adds honesty about the unlearned state. No filler.
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 read-only tool with an output schema and safety annotations, the description covers the main purpose and the no-profile edge case. It would be stronger if it explained the project/tracker parameters, but they are optional and not blocking.
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?
There are two optional parameters (project, tracker) with 0% schema description coverage, and the description does not mention them or clarify whether they filter the cached profile. It therefore does not compensate 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 opens with a concrete object ('What this team's tickets look like: template, length, labels, habits') and clarifies the mechanism with 'Reads the cached profile.' This clearly differentiates it from sibling learn_conventions, which implies the profile must be learned elsewhere.
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 tool is positioned as a cached read, and the phrase 'if none has been learned yet' implies the agent should call it when house style is needed after learning conventions. However, it never names alternatives like learn_conventions or states when not to use it, so guidance is mostly implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
learn_conventionsARead-only
Learn how this team writes tickets, and cache the result.
Slow: it reads the comments and linked changes of up to sample closed
tickets, which is a few hundred API calls. Call it once per project, not
once per question.
Pass from_tickets when the user can name good examples - those are taken
as given and nothing is filtered out. Leave it empty and the tracker is
mined instead: closed tickets are ranked by whether a merge request shipped
for them, whether anyone had to reopen them, and how many clarifying
questions they drew before work started.
| Name | Required | Description | Default |
|---|---|---|---|
| keep | No | ||
| sample | No | ||
| project | No | ||
| tracker | No | ||
| from_tickets | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, and the description adds genuine value beyond them: it discloses that the operation is slow (a few hundred API calls) and that it caches the result. This latency and persistence context is not conveyed by the annotations and helps an agent budget for cost.
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 front-loaded paragraphs where each earns its place: purpose first, then cost/frequency, then the two parameter modes. Slightly long but well organized with no filler.
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?
With 5 parameters, no schema descriptions, and two distinct operational modes, the description explains the modes well but leaves keep, project, and tracker unexplained. An output schema exists so return values need no coverage, but the unexplained parameters leave a real gap for a tool this complex.
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 schema description coverage at 0%, the description carries the burden and does explain sample (the cap on tickets read) and from_tickets (take examples as given vs mine the tracker). But keep, project, and tracker are left entirely unexplained, so the description compensates for only 2 of the 5 parameters.
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 states a specific verb+resource ('Learn how this team writes tickets, and cache the result') that clearly distinguishes it from sibling tools that review slips (review_draft, review_ticket) or provide templates (ticket_template, template_gaps). The learning/caching purpose is unmistakable and differentiates it from the surrounding review-and-draft sibling set.
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?
Offers strong operational guidance: 'Call it once per project, not once per question' plus when to use from_tickets vs mining the tracker. However, it never explicitly compares against alternatives or states when-not-to-use — the differentiation from siblings is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
review_draftARead-only
Check a ticket you have written but not created yet.
Call this on your own draft before showing it to the user, and fix
what it finds rather than reporting it. It is the same measurement
review_ticket runs, so a draft that passes here passes there.
This exists so the check happens before the point of no return. Creating the ticket first notifies whoever watches the board and turns every fix into an edit with a history.
| Name | Required | Description | Default |
|---|---|---|---|
| title | Yes | ||
| labels | No | ||
| project | No | ||
| tracker | No | ||
| description | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so the read-only nature is covered. The description adds the equivalence to review_ticket and the rationale for the pre-creation check, which is valuable behavioral context. It does not contradict annotations. The extra instruction to fix rather than report is an agent directive, not a tool trait, so it doesn't inflate the score further.
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 three short paragraphs, front-loaded with the core instruction. The first sentence is direct and actionable. The subsequent paragraphs justify the tool's existence, which is relevant for usage but slightly verbose. Every sentence earns its place, though the rationale could be tightened. Overall 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?
The output schema exists, so return format is covered. The description explains the tool's purpose, when to call it, and its relationship to review_ticket. It does not mention edge cases or error handling, but for a read-only check tool this is adequate. The key context—why this tool exists and what it guarantees—is present.
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 compensate by explaining parameter semantics. It does not. The parameter names (title, description, labels, project, tracker) are self-explanatory in context, but no format, constraints, or relationship is described. For a tool that validates a draft, the description gives no insight into what fields matter or how they are validated, leaving the agent to guess.
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 opens with a clear verb and resource: 'Check a ticket you have written but not created yet.' It explicitly ties the tool to review_ticket, stating it is the same measurement, which distinguishes it from sibling tools like review_ticket and review_open_tickets. No ambiguity remains about what the tool does.
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 explicit when-to-use guidance: 'Call this on your own draft before showing it to the user.' It explains why (point of no return, notifications, edit history) and implies when not to use it (after creation, use review_ticket). This is unambiguous routing to the correct workflow step.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
review_open_ticketsARead-only
Review every open ticket and list them least-aligned first.
A planning tool: the answer to "what needs tidying before we can estimate
any of this". One line per ticket, so call review_ticket for the detail
on the ones that matter.
| Name | Required | Description | Default |
|---|---|---|---|
| label | No | ||
| limit | No | ||
| project | No | ||
| tracker | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish read-only/open-world safety, so the description adds useful behavior by disclosing the sort order and compact one-line output. However, 'every open ticket' is not reconciled with the limit parameter default of 50, and no pagination behavior is described.
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 sentences with no filler; the main action is front-loaded, and both following sentences add behavioral or routing value.
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 purpose, alternative routing, and annotation-protected safety, and an output schema exists. It is not complete for parameter usage, especially limit and filters, and the 'every' vs. default-limit inconsistency leaves a real gap.
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%, yet the description does not explain any of the four optional parameters (label, limit, project, tracker) or their filtering semantics. The agent must infer meaning entirely from parameter names.
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?
States a concrete action ('Review every open ticket') and a distinctive output ordering ('least-aligned first'), which is enough to separate it from sibling review_ticket. The phrase 'One line per ticket' further specifies the granularity.
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 planning context: it is 'the answer to what needs tidying before we can estimate any of this.' It names the alternative tool, review_ticket, for when detail is needed after the review.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
review_ticketARead-only
Measure one ticket against the learned house style.
Every finding cites a count over the exemplar sample. Repeat those numbers to the user - they are the difference between this and generic advice.
| Name | Required | Description | Default |
|---|---|---|---|
| ticket | Yes | ||
| project | No | ||
| tracker | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnlyHint, openWorldHint, and destructiveHint, so the safety profile is covered. The description adds genuinely useful non-obvious behavior: that every finding cites a count over the exemplar sample and that this numerical grounding is the difference between this advice and generic advice. This tells the agent something about output provenance that annotations cannot convey. No contradiction with annotations; 'measure' is consistent with readOnlyHint.
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 tight sentences with zero filler. The purpose sentence is front-loaded, and the second sentence earns its place by adding a critical presentation instruction (repeat the counts to the user). No redundant restatement of the tool name or schema fields.
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 single-ticket comparison tool with an output schema present, the description is largely sufficient: it explains the measurement target, the grounding mechanism (counts over exemplar sample), and how to relay results. The main omission is the role of the two optional parameters, project and tracker, which are used in nearly every call context and deserve a sentence. Output schema covers return values, so that burden is already lifted.
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 compensate, and it only weakly does. The phrase 'one ticket' clarifies that 'ticket' is the object being measured, but 'project' and 'tracker' are entirely unexplained — the agent cannot tell whether they filter the exemplar sample, scope the house style, or constrain the comparison. With two of three parameters undocumented in both schema and description, this is a real 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 first sentence states a specific verb ('Measure'), a clear resource ('one ticket'), and the comparative frame ('against the learned house style'). It distinguishes itself from siblings by scoping to a single ticket, which contrasts with review_open_tickets (bulk) and review_draft (drafts, likely pre-submission). The scope word 'one' plus 'house style' anchors exactly what this tool does.
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?
Usage context is implied through the comparative frame (measure a ticket against house style), but no explicit when-to-use or when-not-to-use guidance is given, and no sibling alternatives are named. It doesn't tell the agent when to prefer this over review_draft or house_style. The only concrete usage instruction is 'Repeat those numbers to the user,' which is a presentation directive rather than a selection rule.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
template_gapsARead-only
Compare the issue template this repository declares with the tickets it gets.
Reads .github/ISSUE_TEMPLATE or .gitlab/issue_templates from the
checkout and lines each field up against how often tickets actually carry
it. The gap is the finding, and it runs both ways:
A required field almost nobody fills in is a form asking for something people cannot easily supply. Say so: the cheap fix is to change the form, not to nag the team.
A section most tickets carry that no form mentions is a convention the project grew and never wrote down. Adding it to the template is how it survives the next person who joins.
Use this when asked how to improve a board rather than one ticket. It is the only tool here that reads what the project said it wanted, instead of only what it does.
| Name | Required | Description | Default |
|---|---|---|---|
| repo | No | ||
| project | No | ||
| tracker | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, openWorldHint=true, and destructiveHint=false, so the safety profile is known. The description adds behavioral detail beyond that: it reads `.github/ISSUE_TEMPLATE` or `.gitlab/issue_templates` from the checkout, performs a bidirectional gap analysis, and explains what each type of gap signifies. This transparency helps the agent anticipate the tool's findings without contradicting the annotations.
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 and front-loaded with the core purpose, followed by the underlying mechanism and the two types of findings. It uses a clean bullet-like presentation for the gap directions. While it is slightly verbose, each sentence contributes meaningful information, and nothing is redundant or wasted.
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 has moderate complexity: it reads template files and ticket data, performs comparative analysis, and has an output schema to handle results. The description covers the input behavior, the analysis logic, and the significance of the two gap directions, which is sufficient for an agent to understand what the tool does and how to interpret its output. The only notable omission is explicit parameter meaning, but given the output schema exists and the overall logic is well explained, this is a minor gap.
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 three optional parameters (repo, project, tracker) with 0% schema description coverage, so the description must compensate by explaining what these parameters mean. However, the description never mentions them explicitly; it only references 'the checkout,' leaving it unclear how the parameters select which repository or project to examine. The agent would have to infer the parameter semantics from the tool name and context, which is insufficient given the lack of schema documentation.
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: comparing the issue template a repository declares with the tickets it actually receives. It uses specific verbs ('Compare', 'Reads', 'lines up') and explicitly differentiates itself from siblings by noting it is the only tool that reads what the project said it wanted, rather than only what it does. This leaves no ambiguity about the tool's function or how it differs from nearby alternatives.
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 explicitly gives usage context: 'Use this when asked how to improve a board rather than one ticket.' It also distinguishes the tool from siblings by explaining it reads declared intent versus observed behavior. This gives clear when-to-use guidance and effectively excludes the wrong scenario (improving a single ticket), making it easy for an agent to choose correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ticket_contextARead-only
Gather what is known about a subject before you write the ticket for it.
Call this together with ticket_template, then write the ticket
yourself. This returns evidence, not prose - and specifically the
evidence you cannot get by reading the repository:
which past tickets covered this ground, so you can say whether this is a duplicate before anyone spends a week on it;
which files the merge requests for those tickets actually changed. That exists only in the tracker's history. It is usually the fastest way to find where the work will land, and it is worth naming in the ticket.
which files in the checkout mention the subject, as a starting point for your own reading.
Read the files it points at before drafting. The list is a search result, not an understanding of the code, and it will include things that merely share a word.
| Name | Required | Description | Default |
|---|---|---|---|
| repo | No | ||
| project | No | ||
| subject | Yes | ||
| tracker | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true, openWorldHint=true, and destructiveHint=false. The description adds meaningful behavioral detail beyond these annotations: it states the output is 'evidence, not prose', highlights that the file list is 'a search result, not an understanding of the code', and even notes it may include irrelevant matches ('things that merely share a word'). This transparently sets expectations about the tool's limitations and nature, which is exactly what the dimension asks for.
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 longer than average but well-structured with a clear instruction up front, followed by bullet points that add value. Every sentence serves a purpose: defining scope, explaining the return type, listing evidence types, and giving a caution. It is front-loaded with the core directive and does not waste words, so the length is justified.
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 tool that searches across tickets, MRs, and checkout files, the description covers what the tool returns, the caveats, and the recommended usage flow. An output schema exists, so the return structure is likely defined there; the description doesn't need to repeat it. The only missing element is a concrete note on parameter syntax or edge cases, but given the output schema and the detailed behavioral notes, the description is sufficiently complete for an agent to call it 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 input schema provides no descriptions for its parameters and the schema_description_coverage is 0%. The description mentions 'subject' implicitly in the purpose line ('a subject') but does not explain how to use `repo`, `project`, or `tracker`. With zero schema coverage, the description needed to compensate by clarifying these parameters, but it does not. The agent is left to guess what each parameter means, making this a notable 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 opens with a clear, specific directive: 'Gather what is known about a subject before you write the ticket for it.' It explicitly lists what it returns (evidence, past tickets, files changed, file mentions) and contrasts it with prose. It also names the sibling `ticket_template` and positions itself as complementary, making the tool's distinct role immediately apparent.
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 an explicit, actionable workflow: 'Call this together with `ticket_template`, then write the ticket yourself.' It further instructs the agent to 'Read the files it points at before drafting' and warns against treating the list as understanding. This leaves no ambiguity about when and how to invoke the tool relative to the ticket-writing pipeline.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ticket_templateARead-only
The skeleton to fill in when writing a new ticket here.
Use this before drafting, not after. It returns the sections this team actually uses and the length they actually write - then write the ticket yourself. The server has no opinion about the content.
| Name | Required | Description | Default |
|---|---|---|---|
| project | No | ||
| tracker | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds behavioral context by stating the tool 'returns the sections' and that 'the server has no opinion about the content,' clarifying that it only provides a structure and does not validate content. This adds value beyond the annotations.
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 three sentences and front-loads the primary purpose. It is concise, but the wording is slightly informal and could be tightened (e.g., 'the skeleton to fill in' is a bit vague). Still, it avoids fluff and each sentence earns its place.
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 simple optional parameters, the presence of an output schema (which presumably describes the returned template), and annotations covering read-only behavior, the description is sufficient for an agent to know when to call it and what to expect. The only minor gap is the lack of parameter explanation, but that is mitigated by their optionality and defaults.
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%, and the description makes no mention of the 'project' and 'tracker' parameters. While both are optional and have defaults, an agent cannot infer whether they filter the template or influence the returned sections. The description does not compensate for the lack of schema descriptions, leaving parameter semantics unclear.
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: it returns an empty ticket skeleton with the sections and lengths the team uses, to be filled in before drafting. It distinguishes itself from content generation ('write the ticket yourself') and from other workflow tools by specifying it's for the structure, not the 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 explicitly says to use it 'before drafting, not after' and instructs the user to write the ticket themselves afterward, establishing a clear workflow position. It does not explicitly mention sibling alternatives or when not to use it, but the context is sufficient for an agent to understand this is an early-stage template retrieval step.
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.
8 tool updates
v0.1.0- First observed
house_style - First observed
learn_conventions - First observed
review_draft - First observed
review_open_tickets - First observed
review_ticket - First observed
template_gaps - First observed
ticket_context - First observed
ticket_template
TDQS
Scored across 8 tools
Most tools have clear, distinct purposes: house_style and learn_conventions are related but house_style reads the cache while learn_conventions populates it, which is well-communicated. review_ticket and review_draft are similar but review_draft explicitly targets unpublished drafts)Skip, so they are distinguishable. template_gaps and ticket_template serve different functions (gap analysis vs skeleton). The one potential confusion is review_ticket and review_draft, but the descriptions clearly differentiate them.
Most tools follow a noun_action pattern (e.g., learn_conventions, review_ticket, review_open_tickets), but there are inconsistent verb placements and some names are less clear: house_style is a noun phrase, ticket_template is a noun phrase, and template_gaps is a noun phrase without a verb. This mixes patterns (verb-first vs noun-first) and some names are not imperative verbs, which is inconsistent.
With 8 tools, the count is well within the ideal 3-15 range. Each tool has a specific role in the ticket lifecycle: learning conventions, retrieving templates, gathering context, reviewing drafts, reviewing created tickets, and reviewing the open board. No tool feels redundant, and the set is tightly scoped to the server's purpose of ticket style analysis and validation.
The tool set covers the full lifecycle: learning conventions (learn_conventions, house_style), generating templates (ticket_template), gathering context (ticket_context), checking gaps (template_gaps), and reviewing both drafts and existing tickets (review_draft, review_ticket), plus batch review (review_open_tickets). There are no obvious missing operations for the stated purpose; if anything, the coverage is thorough.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Your team's shipping standards, org map and delivery metrics, inside your coding agent.
Read-only AI coding tools for change verification, release readiness, capacity, and guidance.
- ShipstarOAuthai.shipstar
Generate changelogs, release emails, help-center articles, banners, and social posts from commits.
Loads your personal writing voice into any AI and scores how closely a draft matches it.
Related MCP Servers
- AlicenseAqualityAmaintenanceEnables natural-language interaction with self-hosted Jira and Bitbucket, providing tools for ticket management, pull requests, code review, and git context.105461MIT
- AlicenseAqualityCmaintenanceGenerates commit messages, PR titles and descriptions, and release notes from git changes, with automatic domain detection for appropriate PR templates.10131MIT
- FlicenseNot gradedqualityDmaintenanceEnforces team engineering standards across Git, code review, Rails, frontend, deployment, incidents, observability, API design, database, ADRs, and technical debt, with tools for branch name and commit message validation.-
- AlicenseAqualityAmaintenanceEnables AI assistants and developers to analyze code for language-specific best practices and idiomatic patterns across programming languages, CI automation, and configuration formats.162MIT