Skip to main content
Glama

helpdesk-mcp

A customer support helpdesk exposed over the Model Context Protocol (MCP), plus an AI agent that triages tickets through it.

Plug the server into Claude Desktop (or any MCP client) and the model can search tickets, read customer history, look up knowledge base articles and leave notes. Or run the included agent, which connects to the server over MCP, discovers its tools at runtime, and asks a person before it changes anything.

It runs with no API key: an offline demo model drives the agent, so you can clone it and see it work in a minute.

CI

$ helpdesk-agent --yes "Triage the urgent open tickets"
model: demo-offline   server: helpdesk-mcp over stdio

model  I'll find the urgent open tickets first.
call   search_tickets({"status": ["open"], "priority": ["urgent"], "limit": 3})
result {"result": [{"id": 2, "subject": "Charged twice for October", "priority": "urgent", ...
model  Reading 3 ticket(s).
call   get_ticket({"ticket_id": 2})
call   get_ticket({"ticket_id": 1})
call   get_ticket({"ticket_id": 3})
model  Checking the knowledge base for each one.
call   search_kb({"query": "Teachers locked out after SSO change"})
result {"result": [{"slug": "sso-setup", "title": "Setting up single sign-on (SSO)", ...
call   add_comment({"ticket_id": 3, "body": "Triage: urgent account ticket from an enterprise customer. Relevant article: sso-setup ...
model  Triage summary:
- #2 Charged twice for October (urgent, billing): article `refund-policy`.
- #1 Invoices export is empty since the update (urgent, bug): article `export-data`.
- #3 Teachers locked out after SSO change (urgent, account): article `sso-setup`.
I left an internal note on each ticket. Nothing was sent to customers.

5 model turns, 5,048 tokens, 0.1s

What the server exposes

Kind

Name

What it does

Tool (read)

search_tickets

Text search plus filters for status, priority, category and unassigned. Most urgent first.

Tool (read)

get_ticket

Full ticket with customer and comments.

Tool (read)

get_customer

Company and plan. Email addresses are masked.

Tool (read)

search_kb

BM25 search over knowledge base articles.

Tool (read)

ticket_stats

Counts by status and priority, unassigned work, oldest open ticket.

Tool (write)

add_comment

Internal note by default, or a customer-facing reply.

Tool (write)

update_ticket

Status, priority and assignee, following the ticket workflow.

Tool (write)

create_ticket

Open a ticket for a customer.

Resource

helpdesk://tickets/{id}

A ticket as JSON.

Resource

helpdesk://kb, helpdesk://kb/{slug}

Knowledge base index and articles as Markdown.

Resource

helpdesk://audit

The latest writes, with who made them.

Prompt

triage_ticket, draft_reply

Reusable instructions for common jobs.

Related MCP server: TicketDesk MCP

Safety by design

An MCP server hands real capabilities to a model, so the limits live in code, not in the prompt:

  • Typed, bounded inputs. Every tool argument has a type and limits (ids at least 1, text length caps, enums for status and priority). The SDK rejects bad input before any of my code runs.

  • Business rules the model can't skip. Status changes follow a fixed workflow, and closed tickets are final. A refused change comes back as a clear error the model can act on.

  • Read-only mode. --read-only doesn't register the write tools at all, which is a good default for a first connection.

  • Tool annotations. Each tool declares readOnlyHint, destructiveHint and idempotentHint, so clients can decide what needs confirmation.

  • Human approval in the agent. The agent asks before running any tool the server marks as not read-only. A declined action is reported back to the model, which is told not to retry it.

  • Least personal data. Customer emails are masked before they reach the model.

  • Audit log. Every write is recorded with the actor, the action and what changed.

  • Errors that help, crashes that don't leak. Expected failures raise ToolError with a useful message; anything unexpected reaches the model only as a generic error, and the details stay in the server log.

Architecture

flowchart LR
  subgraph Clients
    CD[Claude Desktop]
    AG[helpdesk-agent<br/>agent loop + approval]
  end
  subgraph Server["helpdesk-mcp (MCP server)"]
    T[Tools<br/>typed + annotated]
    R[Resources]
    P[Prompts]
    S[(SQLite store<br/>+ audit log)]
  end
  M{{Model<br/>Claude or offline demo}}

  CD -- stdio --> T
  AG -- "stdio or HTTP" --> T
  AG <--> M
  T --> S
  R --> S

The agent never imports the server's code. It sees only what any MCP client sees, so it works the same against this server or any other.

Getting started

Requires Python 3.11+ and uv.

git clone https://github.com/s-talha/helpdesk-mcp.git
cd helpdesk-mcp
uv sync --group dev

uv run helpdesk-agent "Triage the urgent open tickets"   # asks before each write
uv run helpdesk-agent --yes "Triage ticket 4"           # approve writes automatically
uv run helpdesk-agent --read-only "Triage ticket 4"     # server has no write tools

The demo database (10 customers, 16 tickets, 10 articles) is created at ~/.helpdesk-mcp/helpdesk.db on first run. Pass --db to use another file.

To run the agent on Claude instead of the demo model:

uv sync --extra anthropic
export ANTHROPIC_API_KEY=...
uv run helpdesk-agent "Which unassigned tickets are at risk, and why?"

Use it from Claude Desktop

Add this to claude_desktop_config.json, then restart Claude Desktop:

{
  "mcpServers": {
    "helpdesk": {
      "command": "uv",
      "args": ["--directory", "/path/to/helpdesk-mcp", "run", "helpdesk-mcp", "--read-only"]
    }
  }
}

Remove --read-only once you're happy for Claude to add notes and update tickets.

Run over HTTP

uv run helpdesk-mcp --http --port 8000          # Streamable HTTP at http://127.0.0.1:8000/mcp
docker build -t helpdesk-mcp . && docker run -p 8000:8000 helpdesk-mcp

Tests

uv run pytest

40 tests cover the store (search ranking, workflow rules, masking, audit), the server through a real MCP client (schemas, annotations, read-only mode, invalid input, resources, prompts), and the agent (an end-to-end triage, declined approvals, read-only runs, step limits, and errors fed back to the model). Two tests start the server as a subprocess and talk to it over stdio, exactly as Claude Desktop does.

All tests use the offline demo model, so CI needs no secrets.

Project layout

src/helpdesk_mcp/
  models.py        domain models and the status workflow
  store.py         SQLite store: queries, search, audit log
  seed.py          deterministic demo data
  server.py        the MCP server: tools, resources, prompts
  __main__.py      helpdesk-mcp command (stdio or HTTP)
  agent/
    loop.py        agent loop over an MCP client, with approval and step limits
    providers.py   Claude provider and the offline demo model
    cli.py         helpdesk-agent command
tests/

License

MIT

Available Tools

8 tools
add_commentA

Add a comment. Internal notes (the default) are only visible to support staff.

ParametersJSON Schema
NameRequiredDescriptionDefault
bodyYes
internalNo
ticket_idYesTicket id, for example 3.

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
bodyYes
authorYes
internalYesInternal notes are visible to agents only, never to the customer.
created_atYes

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false, destructiveHint=false and openWorldHint=false, so the write/non-destructive profile is covered. The description does add one genuinely useful trait beyond them — internal notes are visible only to support staff — but says nothing about permissions required, whether a public comment notifies the customer, or any rate limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with zero filler, and the visibility constraint for the default mode is front-loaded where an agent will see it before deciding on parameters.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a low-complexity, 3-parameter write tool with annotations covering safety and an output schema covering return values, the description addresses the main failure mode (posting a support-only note thinking it is public). It could still mention the public/internal routing more explicitly, but nothing essential is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is only 33% (ticket_id is the one documented parameter), so the description must carry weight — and it does, explaining that 'internal' defaults to a support-staff-only note, which the schema does not convey at all. The body parameter remains unexplained, which keeps it from a 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Add a comment'), so the action is unambiguous, but it never says the comment attaches to a ticket — the reader must infer that from the ticket_id parameter and the sibling set (search_tickets, get_ticket, update_ticket). No sibling differentiation is offered, so it falls short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no statement of when to use this tool versus update_ticket or the other siblings, and no prerequisites are given. The note about internal notes implies a choice between internal and customer-visible comments, but that choice is never framed as guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_ticketC

Open a new ticket for a customer.

ParametersJSON Schema
NameRequiredDescriptionDefault
bodyYes
subjectYes
categoryNohow_to
priorityNonormal
customer_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
bodyYes
statusYes
subjectYes
assigneeYes
categoryYes
commentsYes
customerYes
priorityYes
created_atYes
updated_atYes
customer_idYes

TDQS

C2.4/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false, destructiveHint=false and openWorldHint=false, so the safety profile is covered. The description adds nothing beyond that: it does not say whether the ticket is auto-assigned, whether notifications are sent, or what status a new ticket starts in.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single short sentence is front-loaded and free of waste, so it is not verbose. However, at this level of triviality it is under-specification rather than true conciseness for a 5-parameter mutation tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return values need not be explained, and annotations cover the safety profile. Still, for a creation tool with 5 parameters, defaults, and validation bounds, the description omits required inputs, default behavior, and side effects, leaving real gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

All 5 parameters have 0% schema description coverage and the description documents none of them. Notably absent are the category and priority enums with their defaults ('how_to' and 'normal') and the length limits on subject and body, leaving the agent with no semantic guidance whatsoever.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Open a new ticket'), and the word 'new' implicitly separates it from update_ticket and add_comment. It does not explicitly name or differentiate from any sibling, but an agent can tell this is a creation tool without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance, no prerequisites (e.g. customer must exist), and no mention of alternatives such as updating an existing ticket or adding a comment to one. The agent must infer all routing from the tool name alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_customerB
Read-only

Get a customer's company and plan. The email address is masked.

ParametersJSON Schema
NameRequiredDescriptionDefault
customer_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
nameYes
planYes
emailYesMasked: the local part is hidden to keep personal data out of model context.
companyYes

TDQS

B3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description contributes one genuinely non-obvious behavioral fact — the email address is masked — but says nothing about lookup failures, missing customers, or rate limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, front-loaded with the purpose, and the masking note is relevant rather than filler. No wasted words, though the second sentence could have been folded into the first.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained in prose. For a trivial single-parameter lookup the description is close to adequate, but the total absence of usage context and parameter meaning leaves a real gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% and the description says nothing about customer_id — not its origin, format, or whether it is an internal ID versus a public identifier. The single integer parameter is simple, but the description makes no attempt to compensate for the schema gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Get a customer') plus the fields returned (company, plan). It is clear, but the sibling list is entirely ticket-oriented, so there is no peer tool it needs to be disambiguated from, and it does not articulate its scope relative to any of them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use guidance, no prerequisites, and no alternatives mentioned. It never says whether this is the right tool for looking up a customer referenced by a ticket, or what to do when the ID is unknown.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_ticketA
Read-only

Get one ticket with its full text, the customer and all comments.

ParametersJSON Schema
NameRequiredDescriptionDefault
ticket_idYesTicket id, for example 3.

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
bodyYes
statusYes
subjectYes
assigneeYes
categoryYes
commentsYes
customerYes
priorityYes
created_atYes
updated_atYes
customer_idYes

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description adds the useful fact that comments and customer data are expanded into the response, but says nothing about behavior for a missing/invalid id or any size limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence, front-loaded with the verb and resource, with zero filler. Everything stated (full text, customer, comments) is load-bearing information about the payload.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter read tool with an output schema that documents the return shape, the description is close to sufficient. Only the absent error/not-found behavior keeps it from being fully complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Only one parameter and schema description coverage is 100%, so the schema ('Ticket id, for example 3.') already carries full meaning. The description adds no additional format or sourcing guidance for the id, making 3 the correct baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clear verb ('Get') plus resource ('one ticket') with an explicit payload scope: full text, the customer, and all comments. It is distinguishable from the plural sibling search_tickets by the singular, single-record framing, though it never names that sibling explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied by the required ticket_id: retrieve one known ticket by id. There is no statement of when to prefer this over search_tickets when the id is unknown, nor any exclusions or prerequisites.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_kbB
Read-only

Search knowledge base articles. Read the full article with the helpdesk://kb/{slug} resource.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYes
categoryNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description usefully adds that results are abbreviated and full content lives behind a resource URI, but says nothing about result limits, ranking, or empty-match behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, zero filler, with the core action front-loaded and the follow-up instruction second. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, and the resource pointer covers post-search behavior. The gap is the undocumented 'category' filtering dimension, which an agent would not discover without inspecting the schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the burden — and it does not. The 'category' filter (with its billing/bug/account/how_to enum) is never mentioned, and no meaning is added for 'query' beyond the obvious. The agent must open the schema to learn a filterable dimension exists.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Search knowledge base articles'), which is inherently distinct from the ticket/customer siblings. However, it never explicitly contrasts itself with siblings like search_tickets, so the differentiation must be inferred from the resource noun.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives next-step guidance ('Read the full article with the helpdesk://kb/{slug} resource'), which implies search returns partial results and full content requires a follow-up. It offers no when-to-use vs when-not-to-use framing and no mention of alternatives, so usage is only implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_ticketsB
Read-only

Find tickets by text and filters. Results are sorted most urgent first, then oldest first.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
queryNoWords to search for. Leave empty to match everything.
statusNo
categoryNo
priorityNo
unassigned_onlyNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description adds genuinely non-obvious behavior — the ordering rule (most urgent first, then oldest first) — but says nothing about pagination beyond the schema's limit, result truncation, or what matching means (substring vs token).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, the operational purpose first and the ordering guarantee second. Nothing is padded and the most decision-relevant behavior is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, and the safety profile is in annotations. However, for a six-parameter search tool the filter-combination semantics remain undocumented, which is the main thing that could cause a malformed or over-narrow query.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is only 17%: only 'query' has a description. The description's phrase 'text and filters' does not explain the key ambiguity for the three array filters — whether multiple values are OR-ed within a field and AND-ed across fields — nor what unassigned_only overrides. With low coverage, the description needed to compensate and does not.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Find') and resource ('tickets') plus the two mechanisms of retrieval: text and filters. It is distinguishable from get_ticket (single fetch) by implication, but it never explicitly contrasts with its siblings such as search_kb or ticket_stats.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No explicit when-to-use guidance, no exclusions, and no reference to any of the seven sibling tools. The agent must infer that this is the discovery tool before reaching for get_ticket or ticket_stats, and nothing tells it whether search should precede direct retrieval.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ticket_statsB
Read-only

Counts by status and priority, unassigned work, and the age of the oldest open ticket.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
by_statusYes
unassigned_openYes
by_priority_openYesOpen and pending tickets by priority.
oldest_open_hoursYes

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds behavioral value by disclosing which aggregates are returned, but says nothing about the scope of the aggregation (all tickets vs. a subset), whether the counts are cached, or any rate/refresh behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single short sentence with no wasted words, and the most distinctive metrics are listed first. It is grammatically a fragment with no stated verb, which slightly reduces clarity but not length efficiency.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, the description need not explain return values, and with zero parameters there are no inputs to document; annotations cover the safety profile. The only residual gap is that the aggregation scope (which tickets are counted) is unstated.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the baseline is 4 and there is no parameter semantics for the description to clarify. Nothing here misleads about inputs.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description enumerates exactly what is computed — counts by status and priority, unassigned work, and oldest open ticket age — which is far more specific than a generic 'ticket statistics' phrasing. It is a noun-phrase fragment with no explicit verb, so the agent must infer 'returns aggregate statistics', but the metric list distinguishes it clearly from siblings like search_tickets and get_ticket.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance, no statement of what this tool is for in a workflow, and no mention of alternatives (e.g., use search_tickets when you need individual records rather than aggregates). The agent must infer the routing from the metric list alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_ticketA
Idempotent

Change status, priority or assignee. Status changes follow the workflow: open <-> pending, open/pending -> resolved, resolved -> open or closed. Closed is final.

ParametersJSON Schema
NameRequiredDescriptionDefault
statusNo
assigneeNo
priorityNo
unassignNo
ticket_idYesTicket id, for example 3.

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
bodyYes
statusYes
subjectYes
assigneeYes
categoryYes
commentsYes
customerYes
priorityYes
created_atYes
updated_atYes
customer_idYes

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare this as a non-read-only, idempotent, non-destructive mutation, so safety is covered. The description adds genuinely new behavioral context beyond them: the state machine for status transitions and the terminal nature of 'closed', which an agent cannot derive from the enum alone.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences with the core action front-loaded and the constraint detail following; every clause carries information and nothing is padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return values need no explanation, and annotations cover the safety profile. However, for a 5-parameter mutation tool with 20% schema coverage, the undisclosed 'unassign' parameter and the ambiguous relationship between assignee and unassign leave a real functional gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 20% (only ticket_id is documented), so the description must compensate. It does explain the meaning and legal transitions of the status parameter, which the enum does not, but it never mentions the 'unassign' boolean or the assignee semantics, leaving two parameters effectively undocumented.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (change) and names the exact mutable fields (status, priority, assignee), which cleanly separates it from read-only siblings like get_ticket and search_tickets. It does not explicitly name or contrast with any sibling, so it stops short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The transition rules implicitly say when a status change is legal, which is useful usage context, but there is no guidance on when to choose update_ticket over add_comment or create_ticket, and no prerequisites or exclusions are stated.

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.

  1. 8 tool updatesv0.1.0
    • First observedadd_comment
    • First observedcreate_ticket
    • First observedget_customer
    • First observedget_ticket
    • First observedsearch_kb
    • First observedsearch_tickets
    • First observedticket_stats
    • First observedupdate_ticket

TDQS

B3.4/5.0

Scored across 8 tools

Disambiguation5/5

Each tool targets a distinct resource and action: search_tickets vs get_ticket (query vs single-fetch), ticket_stats (aggregates) vs search_tickets (filtered lists), get_customer vs get_ticket, and search_kb vs all ticket tools. add_comment and update_ticket also have clearly separate mutation scopes. No tool pair is likely to be confused.

Naming Consistency4/5

Seven tools follow a clean verb_noun pattern (search_tickets, get_ticket, get_customer, search_kb, add_comment, update_ticket, create_ticket). The lone outlier is ticket_stats, which is a noun-only name, a minor deviation from an otherwise predictable convention.

Tool Count5/5

Eight tools is well within the ideal range and each earns its place by covering a distinct capability (search, fetch, create, update, comment, stats, KB, customer). No redundant or filler tools are present.

Completeness4/5

Core helpdesk lifecycle is covered: create/read/search/update tickets, comment, stats, KB search, and customer lookup. Minor gaps exist (no customer listing/search, no comment editing or deletion), but the closed-is-final status workflow makes ticket deletion reasonably unnecessary.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI assistants to search and retrieve support tickets, add notes, close tickets, and access SLA policies through MCP tools, resources, and prompts over Streamable HTTP.
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables AI clients to access and manage an internal support ticket queue through MCP tools, resources, and prompts, including searching and viewing tickets, adding comments, closing tickets with confirmation, reading knowledge base articles, and viewing queue summaries over OAuth-secured Streamable HTTP.
    -