Skip to main content
Glama
wtf-amnn

customer-support-mcp

by wtf-amnn

Customer Support Operations MCP Server

An MCP server that gives an LLM controlled, validated, auditable access to a relational customer-support system — customers, tickets, comments, and a knowledge base.


Problem statement

Support work is spread across a ticketing system, customer records, and an internal knowledge base. Answering a single question — "is this urgent, who should own it, and what does our policy say?" — means reading from all three and then acting on the first.

An LLM is well suited to that reasoning, but not to being handed a database. Direct SQL access has no notion of which state transitions are legal, no validation of what a priority or status may be, no record of who changed what, and no guard on destructive operations. The model would be free to move a closed ticket back to open, invent a priority value, or delete a record without confirmation.

This server is the layer in between. Every action the model can take is an explicitly defined tool with a validated input schema, business rules enforced server-side, and an audit entry attributed to a named actor. The model gets enough access to be useful and no more.


Related MCP server: Xalantis MCP Server

Overview

The server exposes a support-operations database over the Model Context Protocol, implementing all three MCP capabilities:

  • Tools — 13 actions the model can call: customer and ticket CRUD, assignment, commenting, and validated status changes.

  • Resources — 3 URI-addressed read-only views: a customer profile, an aggregated ticket dossier, and knowledge-base articles by category.

  • Prompts — 2 reusable workflows that chain tools and context into a repeatable support procedure.

It runs over stdio (as a local subprocess, e.g. for Claude Desktop) or Streamable HTTP (as a standalone service).


Architecture

The codebase is deliberately layered, and the direction of dependency only ever points downward:

MCP interface   (server.py)          tools, resources, prompts
      │
      ▼
Service layer   (services/)          business rules, audit logging
      │
      ▼
Schemas         (schemas.py)         Pydantic validation
      │
      ▼
Models          (models.py)          SQLAlchemy ORM, constraints
      │
      ▼
Database        (database.py)        engine, session lifecycle

The important property is that the service layer has no knowledge of MCP. create_ticket() is an ordinary Python function taking a validated Pydantic object and a database session. It can be called from a test, a CLI script, or a web API without change. server.py is a thin adapter that translates MCP tool calls into service calls and back into JSON.

This is why the seed scripts can reuse the exact same code paths the model uses — including audit logging — with no duplication.

Validation happens twice, on purpose. MCP generates an input schema from each tool's type hints, so the protocol layer guarantees email is a string. Pydantic then enforces that it is actually an email, that a priority is one of four values, and that a subject is within length limits. Type-correct and valid are different claims.


Tech stack

Component

Choice

Language

Python 3.10+

MCP

MCP Python SDK v2 (MCPServer)

ORM

SQLAlchemy 2.x (typed Mapped[] style)

Validation

Pydantic v2

Database

SQLite

HTTP server

Uvicorn + Starlette (via the SDK)

Package manager

uv


Project structure

customer-support-mcp/
├── app/
│   ├── services/
│   │   ├── audit_service.py      # centralized audit logging
│   │   ├── customer_service.py   # customer CRUD + domain exceptions
│   │   └── ticket_service.py     # ticket lifecycle, state machine, comments
│   ├── context.py                # contextvar-based actor identity
│   ├── database.py               # engine, session factory, init_db
│   ├── models.py                 # SQLAlchemy models
│   ├── schemas.py                # Pydantic Create/Update/Read schemas
│   └── server.py                 # MCP tools, resources, prompts
├── tests/                        # (not yet implemented)
├── seed_articles.py              # knowledge-base seed data
├── seed_data.py                  # customers, tickets, comments seed data
├── migrate_add_actor.py          # one-off migration: audit_logs.actor
├── customer_support.db           # SQLite database (generated)
├── pyproject.toml
└── uv.lock

Data model

Five tables:

customers — name, unique email, optional phone, status (active / inactive), timestamps.

tickets — belongs to a customer; subject, description, priority (low / medium / high / urgent), status (open / in_progress / resolved / closed), optional assigned team, timestamps. Indexed on (status, priority) since that is the most common query shape.

ticket_comments — belongs to a ticket; author, body, timestamp.

knowledge_articles — slug (unique, human-readable), title, category, body. Reference content, not operational state.

audit_logs — action, entity type, entity id, actor, JSON details, timestamp. Written for every mutating operation.

Relationships cascade: deleting a customer deletes their tickets, and deleting a ticket deletes its comments. Enum-like columns are guarded by CheckConstraints at the database level in addition to Pydantic validation, so invalid values cannot be written even by code that bypasses the schemas.


Tools

All tools return either a JSON object (or list) on success, or {"error": "..."} on failure. Errors are returned rather than raised so the model receives something readable and actionable instead of a traceback.

Customer tools

Tool

Arguments

Behavior

create_customer_tool

name, email, phone?

Creates a customer. Returns error if the email already exists.

get_customer_tool

customer_id

Fetches one customer. Returns error if not found.

list_customers_tool

status?, limit?

Lists customers, optionally filtered by status.

Ticket tools

Tool

Arguments

Behavior

create_ticket_tool

customer_id, subject, description, priority?

Creates a ticket. Verifies the customer exists first, so a bad id yields a clear "no customer" error rather than a foreign-key violation. New tickets always start open.

list_tickets_tool

status?, priority?, customer_id?, limit?

Lists tickets; filters combine with AND. Invalid filter values return an error listing the valid options.

get_ticket_tool

ticket_id

Fetches one ticket record.

assign_ticket_tool

ticket_id, team

Assigns a ticket to a team. Team names are free-form by design.

add_comment_tool

ticket_id, author, body

Adds a comment to a ticket.

change_ticket_status_tool

ticket_id, new_status

Changes status, enforcing the transition graph below.

resolve_ticket_tool

ticket_id

Convenience wrapper that routes through the same validated transition path.

delete_ticket_tool

ticket_id, confirm

Permanently deletes a ticket and its comments. Refuses unless confirm=true.

Context tools

Tool

Arguments

Behavior

get_ticket_details_tool

ticket_id

Returns the aggregated ticket dossier — ticket, customer, and full comment thread — as readable text.

get_knowledge_articles_tool

category

Returns all knowledge-base articles in a category as readable text.

These two are thin wrappers over the resource functions of the same name. See Resources vs tools below for why both exist.

Ticket status transitions

change_ticket_status_tool enforces a state machine rather than allowing arbitrary overwrites:

From

Allowed to

open

in_progress, closed

in_progress

resolved, open, closed

resolved

closed, in_progress (reopened)

closed

— terminal

The valid transitions are also written into the tool's description, so the model knows the rules before calling rather than discovering them through failed attempts. Tool descriptions are treated as prompt engineering, not documentation.


Resources

Resources are read-only, URI-addressed context.

customer://profile/{customer_id} — A customer's profile as formatted text.

ticket://details/{ticket_id} — The full picture for one ticket: its fields, the customer who raised it, and the entire comment history in order. This traverses the ORM relationships to assemble in one read what would otherwise take several tool calls to stitch together.

knowledge://articles/{category} — Every knowledge-base article in a category, rendered as a single document. Categories currently seeded: billing, account.

Resources vs tools

The distinction that matters is who initiates the read:

  • Tools are model-controlled. The model decides to call them, mid-conversation.

  • Resources are application- or user-controlled. The host application surfaces them for a person to attach as context. The model cannot autonomously go and fetch one.

This has a direct practical consequence, discovered while testing: a workflow prompt that instructed the model to "read ticket://details/3" could not be carried out, because the model has no mechanism to fetch a resource on its own.

The fix was to expose the same underlying functions as tools as well (get_ticket_details_tool, get_knowledge_articles_tool) and point the prompts at those. The resources remain, because they still serve their own purpose — a person can attach a ticket dossier or a policy category directly to a conversation with no tool call involved.

Rule of thumb: resources are for the human, tools are for the model. If a workflow needs the model to reach data unprompted, it must be a tool.


Prompts

Prompts are user-invoked, parameterized workflow templates. They are not system prompts, and the model does not trigger them itself — the host surfaces them (typically as a slash command) and the user runs one.

triage-ticket(ticket_id)

A structured triage procedure for a single ticket. It directs the model to:

  1. Read the full ticket dossier, including customer and comment history.

  2. Check the customer's other tickets for a recurring or escalating pattern.

  3. Read the relevant knowledge-base category.

  4. Report a summary, a judgment on whether the current priority is right, a recommended owning team, any applicable article, and a next action.

It ends by instructing the model to present its recommendation and wait rather than acting — a workflow-level counterpart to the tool-level confirm guard.

daily-queue-review()

A standing, parameterless workflow that reasons across the whole queue rather than drilling into one record. It reviews open and in-progress tickets and surfaces urgent tickets that are unassigned, tickets where the customer commented more recently than the support team, and customers with more than one open ticket.

That last item is deliberate: no single tool answers "which customers have multiple open tickets." Rather than adding a narrow find_escalations tool, the prompt describes the analysis and lets the model perform it over list_tickets_tool results. This is what prompts unlock that tools alone do not.


Design decisions

The service layer does not commit. log_action() and every service function call session.flush(), never session.commit(). The caller's session context manager owns the transaction, so an audit entry and the action it describes succeed or fail together. A failed operation leaves no misleading log entry behind.

Domain exceptions, not sentinel returns. Services raise CustomerNotFoundError, DuplicateEmailError, TicketNotFoundError, and InvalidStatusTransitionError. The MCP layer catches these specifically and converts them into clean error messages, which keeps SQLAlchemy internals out of the model's view.

Actor identity via context variables. The audit log records who, not just what. Rather than threading an actor parameter through every service signature, identity lives in a contextvars.ContextVar set once at the entry point. Only audit_service.py reads it; no other service function changed. actor_context() scopes it correctly with proper reset semantics, which is what per-request identity requires under concurrency.

Confirmation on destructive actions. delete_ticket_tool refuses to act unless confirm=true, and its description states the action is irreversible. Combined with the host's own tool-approval prompt and the prompts' present-then-wait instruction, deletion has three independent checkpoints.

Filter normalization and explicit validation. list_tickets_tool strips and lowercases its filters (so "", " ", and "Open " all behave sensibly) and rejects unrecognized values with a message listing the valid ones. Without this, a typo and a genuinely empty result are indistinguishable — the model would report "there are no tickets" when it had simply passed a bad filter. Bad input and an empty result must never look the same.

Idempotent seeds and migrations. Both seed scripts skip records that already exist, and migrate_add_actor.py checks for the column before altering the table. All three are safe to run repeatedly.


Setup

uv sync                       # or: pip install -r requirements.txt

# create tables
uv run python -c "from app.database import init_db; init_db()"

# seed data
uv run seed_articles.py
uv run seed_data.py           # add --reset to wipe existing records first

Running

stdio (default — for Claude Desktop and other local hosts):

uv run app/server.py

Streamable HTTP (for the MCP Inspector or a remote client), on port 3001 at /mcp:

MCP_TRANSPORT=http uv run app/server.py

The HTTP entry point builds the ASGI app explicitly and adds CORS middleware exposing the Mcp-Session-Id header, which browser-based clients such as the Inspector require for session tracking.

Environment variables:

Variable

Purpose

Default

MCP_TRANSPORT

Set to http for Streamable HTTP; otherwise stdio

stdio

MCP_ACTOR

Identity recorded in the audit log

local

Connecting Claude Desktop

Claude Desktop launches the server itself over stdio. In claude_desktop_config.json:

{
  "mcpServers": {
    "customer-support": {
      "command": "uv",
      "args": ["--directory", "/path/to/customer-support-mcp", "run", "app/server.py"],
      "env": { "MCP_ACTOR": "your-name@claude-desktop" }
    }
  }
}

Note that Claude Desktop cannot reach the HTTP mode on localhost: custom connectors are fetched from Anthropic's infrastructure, so 127.0.0.1 there refers to their host, not yours. Reaching it that way requires a public HTTPS URL (via a tunnel or a deployment).

Inspecting

npx -y @modelcontextprotocol/inspector uv run app/server.py    # stdio
npx -y @modelcontextprotocol/inspector                          # then connect to http://127.0.0.1:3001/mcp

Limitations and future work

No test suite. tests/ is scaffolded but empty. The service layer was built to be testable — pure functions over an injected session — so the main task is a fixture providing an isolated database per test rather than the live customer_support.db.

SQLite write concurrency. SQLite serializes writes. This is fine for a single stdio client, but under HTTP with concurrent requests it will produce database is locked errors. Everything goes through SQLAlchemy, so migrating to PostgreSQL is largely a connection-string change — though the SQLite-specific PRAGMA foreign_keys hook and check_same_thread connection argument would become dead code, and DuplicateEmailError depends on catching an IntegrityError that Postgres raises differently.

Actor identity is asserted, not authenticated. MCP_ACTOR is configuration, not proof. Over stdio that is defensible — the host launched the process. Over HTTP it is not: identity should come from a verified token per request, which is what actor_context() was designed to support but which is not yet wired up.

Schema changes are manual. Tables are created with create_all(), which cannot alter existing tables — hence the hand-written migrate_add_actor.py. Alembic would replace this properly.

Customer update and delete are not exposed. update_customer() and delete_customer() exist and are tested manually in the service layer, but no MCP tool wraps them. Deleting a customer cascades to all their tickets and comments, so exposing it warrants at least the same confirmation guard as ticket deletion.

Knowledge-base categories are implicit. billing and account are conventions established by the seed data, not constrained values. A category with no articles returns an empty-result message rather than an error.

Available Tools

13 tools
add_comment_toolC

Add a comment to a ticket.

Args:
    ticket_id: The ticket to comment on.
    author: Who is writing the comment.
    body: The comment text.
ParametersJSON Schema
NameRequiredDescriptionDefault
bodyYes
authorYes
ticket_idYes

TDQS

C2.9/5.0
Behavior2/5

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 discloses only the action itself and does not describe side effects, whether the ticket must exist, who may comment, or any behavior after the comment is added. This is minimal for a mutation tool.

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?

The description is short and front-loaded with the primary action, followed by simple parameter lines. There is no irrelevant content, though the Args section adds limited value beyond the schema.

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?

For a three-parameter write operation with no output schema and no annotations, the description reaches a minimum viable level: the purpose and each parameter are understandable. However, it omits behavioral context such as return values, permission requirements, and failure conditions, so it is not complete enough to confidently exploit the tool in varied contexts.

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 0%, so the Args lines are the only semantics. They do add basic meaning ('author: Who is writing the comment'), but the descriptions are mostly restatements of the parameter names and offer no constraints, examples, or edge-case guidance.

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 states a specific verb and resource: 'Add a comment to a ticket.' This clearly identifies the action and the object, and it is distinct from the sibling tools, which generally handle customer, ticket, assignment, or status operations. It does not explicitly contrast with siblings, 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 Guidelines2/5

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

The description provides no guidance on when to use this tool versus the alternatives, nor does it mention any prerequisites or exclusions. An agent gets no context about when a comment is appropriate compared to using create_ticket or change_ticket_status.

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

assign_ticket_toolC

Assign a ticket to a support team.

Args:
    ticket_id: The ticket to assign.
    team: Name of the team, e.g. 'billing_team' or 'security_team'.
ParametersJSON Schema
NameRequiredDescriptionDefault
teamYes
ticket_idYes

TDQS

C2.6/5.0
Behavior2/5

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

No annotations are provided, so the description carries the full burden of behavioral disclosure. The description only states the action and parameters, but does not disclose what the tool does beyond the assignment (e.g., whether it overwrites existing assignments, sends notifications, or has side effects). This is a significant gap for a mutation tool.

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?

The description is efficient, with a clear action statement followed by parameter explanations in an Args block. It is well-structured and front-loaded with the purpose. No unnecessary content is present, making it concise and easy to parse.

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?

Given that this is a mutating tool with no annotations ****and no output schema, the description is incomplete for an agent to call it correctly. It lacks information on expected behavior, edge cases (e.g., invalid team names), and any side effects. For an agent to use it safely, more context is needed, such as whether team names are validated or if assignment is idempotent.

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?

The schema has zero description coverage, so the description must compensate. The description adds meaning to the 'team' parameter by giving examples (e.g., 'billing_team' or 'security_team'), which is helpful, and identifies 'ticket_id' as the ticket to assign. However, it doesn't specify the expected format for ticket_id or provide more detail beyond the schema, so it only partially compensates.

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

Purpose3/5

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

The description states a clear action ('Assign a ticket to a support team') with a specific resource and target. It is distinguishable from siblings like 'change_ticket_status_tool' and 'resolve_ticket_tool' because it focuses on assignment rather than status changes or resolution, but it doesn't explicitly differentiate itself from other assignment-like tools, so it's adequate but not exceptional.

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?

The description provides no guidance on when to use this tool versus alternatives. It doesn't mention prerequisites, such as whether the ticket must be unassigned or what happens if it's already assigned, nor does it reference sibling tools. This leaves the agent to infer usage context, which is insufficient for a mutating operation.

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

change_ticket_status_toolA

Change a ticket's status. Only valid transitions are allowed.

Valid transitions: open -> in_progress/closed; in_progress -> resolved/open/closed;
resolved -> closed/in_progress; closed is terminal.

Args:
    ticket_id: The ticket to update.
    new_status: One of 'open', 'in_progress', 'resolved', 'closed'.
ParametersJSON Schema
NameRequiredDescriptionDefault
ticket_idYes
new_statusYes

TDQS

A3.7/5.0
Behavior4/5

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

With no annotations, the description carries the behavioral burden: it explicitly states that only valid transitions are allowed and enumerates the full state machine, including the terminal closed state. It does not mention failure behavior or side effects, but the core behavior is well disclosed.

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?

The description is compact and front-loads the core purpose, followed by a clear transition table and argument glossary. No redundant text.

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?

Covers the key invocation context — target object, allowed status values, and legal transitions. It does not state what happens on invalid transitions or describe the response/error behavior, but the state machine is the essential information for safe use.

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 schema has no property descriptions, but the Args section adds meaning: ticket_id identifies the ticket to update, and new_status lists the permitted values. This compensates for the schema's lack of descriptions.

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 action ('change ticket status') with a named resource and gives a precise transition list. It is clear, but it does not distinguish this generic status tool from sibling tools like resolve_ticket_tool or assign_ticket_tool.

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 guidance about when to use this tool versus alternatives. The transition rules are useful constraints, but there is no mention of resolve_ticket_tool/assign_ticket_tool or any other sibling as a better choice for specific cases.

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

create_customer_toolA

Create a new customer record.

Args:
    name: Full name of the customer.
    email: Customer's email address (must be unique).
    phone: Optional phone number.
ParametersJSON Schema
NameRequiredDescriptionDefault
nameYes
emailYes
phoneNo

TDQS

A4/5.0
Behavior3/5

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

With no annotations provided, the description bears the full burden. It does disclose that a new customer record is created and that email must be unique, but it does not state return values, duplicate-email handling, or any side effects beyond the basic creation.

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?

Extremely concise: a one-line purpose followed by a scannable parameter list. Every sentence adds value and there is no filler.

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?

For a simple 3-parameter create tool, the essential invocation details are present. However, without an output schema or annotations, the description should ideally clarify what the tool returns or how conflicts are handled, both of which are absent.

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

Parameters5/5

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

The input schema has 0% description coverage, but the description's Args block fully compensates by defining all three parameters with meaningful details: 'Full name', 'must be unique' for email, and 'Optional' for phone. This is exactly what an agent needs to construct a valid call.

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

Purpose5/5

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

States a specific operation ('Create') and a specific resource ('customer record'), clearly distinguishing it from sibling tools like get_customer_tool, list_customers_tool, and create_ticket_tool. The intent is immediately unambiguous.

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 intended use is implied by the verb 'Create', but there is no explicit guidance on when to prefer this over alternatives, nor any mention of prerequisites. It does not discuss when not to use the tool.

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

create_ticket_toolB

Create a support ticket for an existing customer.

Args:
    customer_id: Id of the customer raising the ticket.
    subject: Short summary of the issue.
    description: Full description of the issue.
    priority: One of 'low', 'medium', 'high', 'urgent'.
ParametersJSON Schema
NameRequiredDescriptionDefault
subjectYes
priorityNomedium
customer_idYes
descriptionYes

TDQS

B3.1/5.0
Behavior2/5

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

No annotations are provided, so the description carries the full burden of behavioral disclosure. The description only states the action and parameters; it doesn't mention side effects, permissions required, whether the ticket is created in a specific state, or what happens on success/failure. For a creation tool, this is a significant gap—an agent doesn't know if this is a safe read-only operation or a mutating one (though 'create' implies mutation).

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?

The description is concise and front-loaded with the purpose statement, followed by a clean parameter list. Every sentence earns its place. The only minor issue is that the parameter list format (Args:) is a bit terse but acceptable for a tool with only four parameters.

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?

Given the tool has no annotations, no output schema, and 0% schema description coverage, the description is incomplete. It doesn't explain what the tool returns (e.g., ticket ID), whether the customer must exist (though 'existing customer' implies it), or any error conditions. For a creation tool with multiple sibling tools, more context is needed for an agent to invoke it correctly.

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 0%, so the description must compensate. The description does list all four parameters with brief explanations (customer_id, subject, description, priority), which adds meaning beyond the bare schema titles. However, it doesn't provide format details (e.g., expected length of subject, whether priority is case-sensitive) or clarify that priority has a default of 'medium' (which the schema shows but the description omits).

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 clearly states the tool's purpose: 'Create a support ticket for an existing customer.' It uses a specific verb ('create') and resource ('support ticket'), and the 'existing customer' qualifier distinguishes it from create_customer_tool. However, it doesn't explicitly differentiate from other ticket-related tools like assign_ticket_tool or add_comment_tool, though the verb 'create' makes the primary purpose clear.

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 implies usage context by specifying 'for an existing customer,' which suggests it should not be used for new customers. However, it doesn't explicitly state when to use this tool versus alternatives like create_customer_tool or assign_ticket_tool. The sibling list includes several ticket-related tools, but no explicit routing guidance is provided.

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

delete_ticket_toolA

Permanently delete a ticket and all its comments. Destructive and irreversible.

Args:
    ticket_id: The ticket to delete.
    confirm: Must be explicitly set to true to proceed with deletion.
ParametersJSON Schema
NameRequiredDescriptionDefault
confirmNo
ticket_idYes

TDQS

A4.2/5.0
Behavior4/5

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

With no annotations, the description carries the transparency burdeneds by mentioning that the operation is destructive, irreversible, and removes the ticket plus all its comments, and that a confirm flag is required. It does not mention permissions or side effects beyond comments, but the core behavioral warnings are present.

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?

Three concise sentences plus a two-line arg list. The destructive nature is front-loaded)Skip supplementary. The text is efficient with no filler.

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 destructive action with no output schema, the description covers the critical information: what will be deleted, irreversibility, and the confirmation requirement. It doesn't specify response behavior, but that is unlikely to prevent correct invocation.

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 description coverage is 0%, so the description must explain the parameters. It does: ticket_id identifies the ticket to deletehola confirm must be explicitly true to proceed. This adds clear meaning not present in the schema.

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

Purpose5/5

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

States a specific verb 'delete', a precise resource ('ticket'), and the full scope ('and all its comments'), making the tool's purpose unambiguous and distinct from sibling ticket tools.

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 clearly indicates when to use the tool (when a ticket must be permanently removed), but it does not explicitly discuss alternatives or conditions that would make another tool more appropriate. The context is clear but exclusions are not stated.

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

get_customer_toolA

Fetch a customer by their id.

Args:
    customer_id: The customer's numeric id.
ParametersJSON Schema
NameRequiredDescriptionDefault
customer_idYes

TDQS

A3.9/5.0
Behavior3/5

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

The verb 'Fetch' clearly indicates a read operation主食, but with no annotations and no further description, behavioral details such as null/not-found behavior, return format, or error handling are absent. The description is not misleading, but it relies on the tool name's implication of read-only.

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?

The description is exceptionally concise and front-loaded: 'Fetch a customer by their id.' The argument documentation is immediately after and minimal. No wasted words.

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 single-parameter getter, the description covers the essential information: what resource and what key. It lacks explicit mention of behavior when the customer is not found or of the return value, but those are not necessary for a simple id-keyed fetch and the sibling tools make the context clear.

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?

The schema provides the parameter name and type (integer), and the description only restates that it is a numeric id. It adds no meaning beyond the schema, such as where to find the id, uniqueness, or format constraints. With 0% schema description coverage, the description should compensate but does not.

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

Purpose5/5

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

The description uses a precise verb-resource pair: 'Fetch a customer by their id.' It clearly identifies the operation, the resource, and the lookup key. This differentiates it from siblings like list_customers_tool (plural) and create_customer_tool (write operation).

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

Usage Guidelines4/5

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

The description makes it clear this is for retrieving a single customer when the id is known. It doesn't explicitly mention when not to use it or name alternatives, but the context is unambiguous given the sibling tool names.

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

get_knowledge_articles_toolA

Read support knowledge-base articles for a category.

Use this to find relevant policy or troubleshooting guidance before
advising on a ticket.

Args:
    category: One of 'billing' or 'account'.
ParametersJSON Schema
NameRequiredDescriptionDefault
categoryYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.4/5.0
Behavior3/5

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

No annotations are provided, so the description carries the full behavioral burden. The verb 'Read' signals a non-mutating operation and the Args section discloses the allowed category values. However, it doesn't disclose deeper behavior such as result limits, error handling for invalid input, or response characteristics; the output schema covers return shape, so a middle score is appropriate.

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?

Three compact components — a purpose statement, an invocation trigger, and parameter values — each earn their place, and the primary purpose is front-loaded. There is no filler or redundant restating of the schema.

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

Completeness5/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, the description covers everything an agent needs to invoke it correctly: what it does, when to use it, and the only input's allowed values. The output schema covers return shape, and the verb 'Read' establishes the safety profile in the absence of annotations.

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

Parameters5/5

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

Schema description coverage is 0% and no enum is declared in the schema, so the category parameter is undocumented in structured data. The description fully compensates by enumerating the exact valid values: 'One of billing or account.' For a single-parameter tool, this is complete parameter semantics.

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

Purpose5/5

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

The opening line 'Read support knowledge-base articles for a category' names a specific verb (Read), a specific resource (support knowledge-base articles), and a scoping dimension (category). Among the sibling tools, all of which operate on customers or tickets, this is the only knowledge-base tool, so an agent cannot confuse it with any sibling.

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

Usage Guidelines4/5

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

The second sentence gives an explicit trigger condition: use this to find policy or troubleshooting guidance before advising on a ticket. This clearly tells an agent when to invoke the tool, though it doesn't include when-not-to-use conditions or name alternatives — a minor gap since no sibling tool covers knowledge articles.

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

get_ticket_details_toolA

Get full context for a ticket: details, customer info, and all comments.

Use this instead of get_ticket_tool when you need the complete picture,
including the customer and the comment history.

Args:
    ticket_id: The ticket's numeric id.
ParametersJSON Schema
NameRequiredDescriptionDefault
ticket_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior3/5

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

No annotations are provided, so the description must disclose behavioral traits. It states the tool 'gets' data and lists what is returned, which implies a read-only operation, but it does not explicitly state it has no side effects or mention authentication requirements. This is adequate but not rich.

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?

The description is extremely concise: two sentences plus a parameter line. The purpose is front-loaded, and every sentence earns its place. No filler or repetition.

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 single-parameter read tool with an output schema, the description covers purpose, usage, and the parameter. It also mentions the content of the response (details, customer, comments). It omits explicit statements about side effects or error cases, but these are unlikely to be critical for a simple GET operation. It is mostly complete, with minor gaps.

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 0%, so the description must compensate. The line 'ticket_id: The ticket's numeric id' adds minimal value—it restates the type (integer) and the property name. It does not provide additional context like where the ID comes from or any constraints, but it is a clear and correct description.

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

Purpose5/5

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

The description clearly states the tool retrieves full ticket context (details, customer, comments) and explicitly contrasts it with the sibling get_ticket_tool, making its unique purpose unmistakable.

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

Usage Guidelines5/5

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

It provides explicit when-to-use guidance: 'Use this instead of get_ticket_tool when you need the complete picture, including the customer and the comment history.' This directly tells an agent when to select this tool over a close alternative.

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

get_ticket_toolC

Fetch a single ticket by id.

Args:
    ticket_id: The ticket's numeric id.
ParametersJSON Schema
NameRequiredDescriptionDefault
ticket_idYes

TDQS

C2.9/5.0
Behavior2/5

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

No annotations are provided, so the description carries the full burden of behavioral disclosure. 'Fetch' implies a read operation, but the description does not mention response format, not-found behavior, error conditions, permissions, rate limits, or any other 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.

Conciseness5/5

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

The description is very short, front-loaded with the action, and every line serves a purpose. There is no redundant prose or filler.

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?

For a simple one-parameter read-only fetch, the description is minimally viable, but it omits output details and does not clarify how it differs from get_ticket_details_tool. Given the existence of that sibling, a bit more context would materially help an agent use the tool correctly.

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%, but the description's parameter line mostly restates what is already evident from the schema: ticket_id is an integer identifier. It adds little semantic nuance beyond the structured field name and type.

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 clearly states a specific action ('Fetch a single ticket') with its resource ('ticket') and input method ('by id'), so an agent can understand the core purpose. However, it does little to distinguish itself from the sibling get_ticket_details_tool, leaving some ambiguity about which ticket-related fetch should be selected.

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 guidance on when to choose this tool instead of alternatives such as get_ticket_details_tool or list_tickets_tool. The description implies usage when one ticket id is available, but it offers no exclusions, conditions, or comparative context.

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

list_customers_toolA

List customers, optionally filtered by status.

Args:
    status: Filter by 'active' or 'inactive'. Omit for all customers.
    limit: Maximum number of customers to return.
ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
statusNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.7/5.0
Behavior3/5

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

With no annotations provided, the description itself must carry behavioral information. It conveys that this is a listing operation, that status can be omitted for all customers, and that limit caps the result size. It does not mention sorting, pagination beyond limit, access/auth expectations, or any side effects—though 'List' implies a read-only operation.

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?

Main action and optionality are stated in one line, followed by a compact Args block covering both parameters. No filler, and the important 'omit for all customers' behavior is included.

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?

The two-parameter surface is simple and the output schema covers return shape, so the description documents what an agent needs for basic use. It lacks sorting/pagination semantics beyond limit and does not compare with sibling retrieval tools, but those gaps are minor for this tool.

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

Parameters5/5

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

The input schema has no descriptions, so the description takes the full burden and succeeds: it defines 'active'/'inactive' values for status, explains that omitting status returns all customers, and specifies limit as the maximum result count.

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 states the action ('List customers') and the optional status filter clearly. It is distinguishable from get_customer_tool by the plural list/resource framing, though it does not explicitly contrast itself with any sibling tool.

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?

The description explains the parameters but gives no guidance about when to prefer this tool over alternatives like get_customer_tool or create_customer_tool. Context like 'use this for the full customer list' or 'use get_customer_tool for one customer' is missing.

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

list_tickets_toolA

List tickets with optional filters. Use this to find tickets matching criteria.

Args:
    status: Filter by 'open', 'in_progress', 'resolved', or 'closed'. Omit for all.
    priority: Filter by 'low', 'medium', 'high', or 'urgent'. Omit for all.
    customer_id: Only tickets belonging to this customer.
    limit: Maximum number of tickets to return.
ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
statusNo
priorityNo
customer_idNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior3/5

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

No annotations are supplied, so the description carries the full burden. It discloses filter defaults and the limit's meaning, but it does not explicitly state read-only/side-effect status, pagination, ordering, or authentication requirements. Since listing is generally low-risk, the gap is moderate.

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?

The description is compact, front-loads purpose, and organizes parameters in an Args block. The opening sentence and the 'Use this to find tickets...' are slightly redundant, but the overhead is minor.

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?

Given the output schema exists and the tool is a simple filterable list with no required fields, the description covers enough of what an agent needs: valid filters, defaults, and maximum count. It omits ordering or explicit pagination, but these are wholly covered by the schema and tool behavior.

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

Parameters5/5

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

Schema description coverage is 0%, so the description must supply semantics. It fully enumerates the valid status values, priority values, explains customer_id as ticket ownership, and defines limit as maximum returned. This adds value beyond the bare type-only schema.

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 states a clear verb and resource: 'list tickets with optional filters'. It implicitly distinguishes itself from singular get_ticket and get_ticket_details tools by using 'list', but it does not explicitly name those siblings.

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

Usage Guidelines4/5

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

It explicitly says 'Use this to find tickets matching criteria' and explains that omitted filters mean all tickets. This is clear context for when to list versus retrieve one ticket. It does not explicitly mention alternatives like get_ticket_tool, but the guidance is strong.

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

resolve_ticket_toolC

Mark a ticket as resolved.

Args:
    ticket_id: The ticket to resolve.
ParametersJSON Schema
NameRequiredDescriptionDefault
ticket_idYes

TDQS

C2.9/5.0
Behavior2/5

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

No annotations are provided, so the description carries the full burden of behavioral disclosure. It only says 'mark as resolved,' with no mention of side effects, permissions, idempotency, or whether the ticket must be in a certain state.

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, front-loaded purpose, and a clean parameter line. No filler or repetition beyond the redundant 'Args' section.

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?

For a single-parameter state-change tool this is minimally adequate: action and parameter are identified. But with no annotations, no output schema, and no differentiation from change_ticket_status_tool, it leaves the agent to guess semantics, return values, and prerequisites.

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 only repeats that ticket_id identifies the ticket to resolve. It adds little beyond the parameter name; no guidance on how to determine valid ticket IDs or any constraints.

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 clearly states the action ('Mark a ticket as resolved') and the target resource. However, it does not distinguish from the sibling change_ticket_status_tool, which may perform a similar status transition.

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 guidance is provided on when to use this tool versus change_ticket_status_tool or other ticket tools. There are no conditions, prerequisites, or exclusions described.

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. 13 tool updatesv0.1.0
    • First observedadd_comment_tool
    • First observedassign_ticket_tool
    • First observedchange_ticket_status_tool
    • First observedcreate_customer_tool
    • First observedcreate_ticket_tool
    • First observeddelete_ticket_tool
    • First observedget_customer_tool
    • First observedget_knowledge_articles_tool
    • First observedget_ticket_details_tool
    • First observedget_ticket_tool
    • First observedlist_customers_tool
    • First observedlist_tickets_tool
    • First observedresolve_ticket_tool

TDQS

A3.6/5.0

Scored across 13 tools

Disambiguation4/5

Most tools are distinct, but get_ticket_tool and get_ticket_details_tool overlap, as do resolve_ticket_tool and change_ticket_status_tool. The descriptions provide clear guidance on when to use each, so an agent can disambiguate, though slight redundancy exists.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern with snake_case, e.g., get_customer_tool, list_tickets_tool, change_ticket_status_tool. No mixed conventions or irregular verbs.

Tool Count5/5

With 13 tools covering customers, tickets, comments, assignments, and knowledge articles, the count is well-scoped for a customer support server. Each tool serves a clear purpose without excessive redundancy.

Completeness4/5

The surface covers core customer and ticket lifecycles: create/get/list for customers, full ticket management (create, list, get, status changes, resolve, assign, comment, delete). Minor gaps include no update/delete for customers and no ability to modify ticket content, but these are not critical for typical support workflows.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables querying and managing a CRM database through natural language conversations with Claude Desktop.
    -
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables natural language queries, CRUD operations, and analytics on a PostgreSQL database (Neon) via Claude, supporting customers, tickets, products, and analytics.
    MIT