Skip to main content
Glama
sus-tech-gmbh

matrix42-mcp

Matrix42 MCP Server

CI npm version node License: MIT MCP PRs welcome

Give your AI assistant a safe, read-only-by-default window into Matrix42.

A Model Context Protocol server that lets an assistant explore a Matrix42 instance the way an experienced consultant would: find the right web service, read the real data model, query records with valid filters, search the service desk, and - only if you switch it on - act on tickets.

The server holds the credentials and talks to Matrix42 on the assistant's behalf: it performs the API-token exchange, sets the Explicit-Language header, and handles TLS. The assistant never sees your credentials.

npx matrix42-mcp --help
IMPORTANT

This is an independent community project. It is not affiliated with, endorsed by, sponsored by, or supported by Matrix42 AG. "Matrix42" is a trademark of its respective owner and is used here only to describe what this software interoperates with. Support comes from the community via GitHub issues - do not contact Matrix42 support about this project, and do not expect a service-level agreement of any kind. It is provided "as is" under the MIT licence.

NOTE

Status: early release. The server is read-only by default - write tools are not even listed unless you set M42_ALLOW_WRITES=1.

Highlights

  • Read-only by default. Write tools are absent from the tool list unless explicitly enabled.

  • Never guesses. Every column is resolved against your instance's live schema before a query runs, so a field your instance does not have is reported - not sent and turned into an opaque 500.

  • Teaches, then acts. Four written guides ship with the server as MCP resources, covering the data model, the schema, the ASQL filter language and the REST conventions.

  • Preview before you write. Every write returns the exact request it would send until you pass confirm. The preview is the same plan object that gets executed, so it cannot drift.

  • Safe defaults where it counts. Notification e-mails are off, journal entries are internal, and cascading closes are opt-in.

  • No Matrix42 code or content. Every guide is original prose that links to the official docs rather than reproducing them.


Related MCP server: VAST DB MCP Server

Table of contents

Understand it

Set it up

Use it

Work on it


Why

Matrix42's API surface is large (a typical instance exposes ~190 web services and ~1,100 operations), plus a data model of ~800 data definitions and ~240 configuration items, and an assistant has no way to know what exists. Point it at this server and it can search for the right endpoint, read the exact contract, and then write correct integration code - instead of guessing at URLs, auth, and headers.


What it can do

Discover the API

~1,100 operations with full request and return contracts, and whether each is update-safe

Understand the model

785 data definitions, 237 configuration items, pickup values, relations and cardinality

Read records

ASQL queries with paging, saved views, journal, attachments, and links into the web interface

Work the service desk

Search seven ticket kinds by name, service levels, thirteen curated domains, or search all of them at once

Act on tickets

Create, close, classify, take over, forward, pause, reopen, set deadlines, track time - each previewed first

What a conversation looks like

You: Which open hardware tickets are still unresolved, and are any past their service level?

The assistant works it out without you naming a single id:

Note what did not happen: no GUID lookups, no guessed attribute names, and nothing was written. Note also what the server refuses: a filter Matrix42 accepts but never applies, so an unfiltered answer is never mistaken for a filtered one.


Requirements

  • Node.js 22.19 or newer (required by undici, the HTTP client)

  • A Matrix42 instance and either an API token (recommended) or basic-auth credentials

Creating an API token

In the Matrix42 Administration application, create an API token for the account the assistant should act as. The server exchanges it for a short-lived access token automatically and re-exchanges it before it expires.

Basic auth is supported but discouraged: many instances accept the credentials yet still refuse API access with 403 because of role/audience restrictions.


Configuration

All configuration is via environment variables.

Variable

Required

Default

Description

M42_HOST

-

Base URL of the instance, e.g. https://matrix42.example.com

M42_API_TOKEN

✅¹

-

API token; exchanged for an access token automatically

M42_USERNAME / M42_PASSWORD

✅¹

-

Basic-auth alternative to M42_API_TOKEN

M42_LANGUAGE

en-US

Response language, sent as Explicit-Language

M42_TOOLS

all

Comma-separated tool ids to expose

M42_ALLOW_WRITES

0

Set to 1 to expose tools that modify data. Write tools are not registered at all unless this is set.

M42_ALLOW_INSECURE_TLS

0

Set to 1 to skip TLS verification (self-signed dev instances only)

M42_AUDIT_NOTE

1

Mark created tickets with an internal note saying they were raised through this server. Set to 0 to disable.

M42_AGENT_LABEL

Matrix42 MCP server

How the assistant is named in that note

M42_UI_URL

discovered

Origin of the web interface, for deep links. Discovered from the instance's web shell config when unset.

M42_TIMEOUT_MS

30000

Per-request timeout

¹ Provide either M42_API_TOKEN or both M42_USERNAME and M42_PASSWORD.


Client setup

The server runs over stdio: your MCP client starts it. No install step is needed - npx fetches it on demand.

Claude Code

claude mcp add matrix42 \
  --env M42_HOST=https://matrix42.example.com \
  --env M42_API_TOKEN=your-api-token \
  -- npx -y matrix42-mcp

Claude Desktop

claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/, Windows: %APPDATA%\Claude\)

{
  "mcpServers": {
    "matrix42": {
      "command": "npx",
      "args": ["-y", "matrix42-mcp"],
      "env": {
        "M42_HOST": "https://matrix42.example.com",
        "M42_API_TOKEN": "your-api-token"
      }
    }
  }
}

Cursor

~/.cursor/mcp.json (global) or .cursor/mcp.json (per project)

{
  "mcpServers": {
    "matrix42": {
      "command": "npx",
      "args": ["-y", "matrix42-mcp"],
      "env": {
        "M42_HOST": "https://matrix42.example.com",
        "M42_API_TOKEN": "your-api-token"
      }
    }
  }
}

VS Code (GitHub Copilot)

.vscode/mcp.json - this shape prompts for the token instead of storing it in the file:

{
  "inputs": [
    { "id": "m42-token", "type": "promptString", "description": "Matrix42 API token", "password": true }
  ],
  "servers": {
    "matrix42": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "matrix42-mcp"],
      "env": {
        "M42_HOST": "https://matrix42.example.com",
        "M42_API_TOKEN": "${input:m42-token}"
      }
    }
  }
}

Other stdio-capable clients (Windsurf, Cline, Zed, …) use the same command / args / env shape.


Verifying the connection

Ask the assistant to call server_info, or run the bundled smoke test against your instance:

git clone https://github.com/sus-tech-gmbh/M42-MCP.git
cd M42-MCP && npm install && npm run build

M42_HOST=https://matrix42.example.com \
M42_API_TOKEN=your-api-token \
node scripts/smoke.mjs

It connects as a real MCP client and exercises every tool.

You can also run the CLI directly:

npx matrix42-mcp --help    # usage and configuration
npx matrix42-mcp --tools   # available tool ids

Tools and actions

Six tools, each grouping a set of actions. Everything the server can do lives here - the read tools first, then the one that writes.

Tool

What it does

server_info

Reports which Matrix42 instance is connected and verifies the credentials work. Never returns credentials.

webservice_discovery

Discovers the REST API. See the actions below.

schema_discovery

Explores the data model: data definitions, configuration items, attributes, relations, pickup values.

data_query

Reads records: ASQL queries, saved views, journal entries, attachments, plus an ASQL guide and validator.

service_desk

Searches tickets of any kind, answers service-level questions, and browses assets, contracts, catalog services, bookings, knowledge articles, approvals, imports and workflow instances.

ticket_actions

Writes - the ticket lifecycle: create, close, take over, forward, pause, reopen, set deadlines, track time, add journal entries. Only present when M42_ALLOW_WRITES=1.

webservice_discovery actions

Action

Parameters

Returns

api_overview

-

General Matrix42 API conventions: token exchange, Explicit-Language, Public vs Product API, common data surfaces. Useful before writing standalone integration code.

list_operations

search?, service_id?, limit?

Operations as {id, name, method, path, service, documentation}. search filters on name, documentation, and service name. Defaults to the first 200 matches; pass limit: 0 for all.

list_services

-

Every web service with its route prefix and documentation.

describe_operation

operation_id

One operation's full contract: HTTP method, path, parameters with types, and return type.

Typical flow: api_overview once → list_operations with a search term → describe_operation on the one you want.

schema_discovery actions

Action

Parameters

Returns

schema_overview

-

How the Matrix42 data model fits together: data definitions vs configuration items, fragments and multi-fragments, cardinality, pickups, and where to find the official docs.

list_data_definitions

search?, include_pickups?, limit?

Definitions as {internalName, displayName, description, classType, isPickup, isCustom}. Pickup classes are excluded unless asked for.

list_configuration_items

search?, limit?

Items with their main class and member definitions.

describe_data_definition

name, include?

Attributes with decoded datatypes and pickup cross-links. Relations are excluded by default (a central definition can have 150+) - pass include: "relations" or "both".

describe_configuration_item

name

The definitions an object is composed of, each with its cardinality and a isMultiFragment flag.

get_pickup_values

pickup_class or name+attribute

The selectable {value, label} pairs - so a model filters on real values instead of guessing codes.

Typical flow: schema_overviewlist_* with a search term → describe_*get_pickup_values before filtering on any pickup attribute.

data_query actions

Action

Parameters

Returns

asql_guide

-

The ASQL expression language used by where and columns: operators, dot chains, pickups, T(...) pivots, subqueries, [Expression-ObjectID].

validate_asql

class, expression

Whether an expression is valid, with the exact error (e.g. "does not contain attribute Nope"). Cheaper than a failed query.

query

class, columns?, where?, sort?, page_size?, page?

Rows plus typed column metadata, with paging (hasMore).

get_fragment

class, fragment_id

One complete fragment.

get_object

ci_name, object_id

One whole object (all fragments of a configuration item).

list_views / run_view

search? / view_id

The instance's saved data queries - curated views that already carry a predefined filter. Prefer a matching view over hand-written ASQL.

list_journal

object_id

An object's comment/activity timeline.

list_attachments

object_id

The files attached to an object.

deep_link

object_id, view_type?

A URL into the Matrix42 web interface - preview, edit, create or run an action. Resolves the object's configuration item itself, so you only need the object id.

Typical flow: asql_guide once → schema_discovery to find the class and its pickup values → validate_asqlquery. Always pass sort when paging; page boundaries are otherwise unstable.

Numeric enums are decoded for you (Datatype: 2"Int", Cardinality: 3"Optional (Multi)"), and customisations are flagged using the custom prefix the instance itself reports.

data_query(action='deep_link') builds a URL an assistant can hand you, in the format Matrix42 documents for deep linking:

https://your-instance/wm/app-ServiceDesk/?view-options={"type":"SPSActivityTypeTicket",
                                                        "viewType":"preview",
                                                        "objectId":"<object id>"}

view_type selects what opens: preview (default, read-only), edit, new for a creation form, or action for a wizard. Only new works without an object id, and action additionally needs an action_id. Nothing is ever changed by opening a link - even edit waits for a person to save.

You only need the object id. A base data definition is reused by many configuration items - SPSActivityClassBase alone backs incidents, service requests and changes - so the server resolves the real one for you rather than making you pick. Pass a wrong ci_name and it corrects it; pass a fragment id and it refuses instead of handing you a link that opens nothing.

Links target the web interface's own origin, not the API host you connected to. Those are often different: an instance reachable at an IP commonly serves its UUX under a real name, and the shell's config.json says which. Loading the shell from the wrong origin leaves the app calling an origin it was not served from, which fails after the page has already appeared to load. The server reads that origin from the instance and reports it as webInterface alongside the link; M42_UI_URL overrides it.

service_desk actions

Action

Parameters

Returns

data_model

-

How Matrix42's modules map onto a handful of base classes - where tickets, assets, licenses, contracts, SLAs and catalog items actually live. Read it when you are unsure where something is.

search_tickets

kind, plus subject, category_name and/or states

Matching tickets. kind is one of ticket, incident, problem, change, task, service_request, kb_article. Other filter parameters exist but Matrix42 ignores them, so passing one is refused.

get_ticket

ticket_object_id

One ticket's summary as the service desk sees it.

sla_for_ticket

ticket_object_id

The service level agreements that apply, as Matrix42 itself computes them.

sla_times

ticket_object_id

Reaction and solution time state.

browse

domain, search?, where?, limit?

Rows of one curated domain, plus the fields this instance does not have.

find

search, domains?, limit?

Searches every domain at once for a name - for when you do not know where something lives. Domains that fail (module not installed) are reported, not fatal.

Every kind shares the same contract, so one call shape covers the whole service desk. Only subject, category_name and states actually filter it - Matrix42 accepts initiator_name, ticket_number, asset_id and the rest, then ignores them and returns every ticket. Passing one is refused rather than handing back an unfiltered result you would read as filtered; the refusal points at data_query with an ASQL where, which does filter on those.

browse domains: assets, stock_units, contracts, slas, catalog_services, bookings, kb_articles, approvals, imports, import_runs, workflow_instances, workflow_definitions, applications. Workflows are read-only - this server lists definitions and instances but never starts, suspends, resumes or cancels them.

Columns are never guessed. Before every browse, the server reads the definition's real attribute list from the instance and keeps only the fields that exist, reporting the rest as unavailableFields. A module you have not licensed therefore yields a shorter row, not a failed call. The same rule is stated in the guides and the server instructions, so a connected model follows it too.

All read tools are annotated readOnlyHint: true, so clients can distinguish them from anything that would change data.

ticket_actions actions (writing data)

Write tools are absent from the tool list unless M42_ALLOW_WRITES=1, so a default deployment cannot modify anything even if a model asks it to. When enabled, ticket_actions offers:

Action

Notes

create_ticket

Returns the new object id, which every other action takes directly.

close_ticket

Closes by object id, with an optional solution and closing reason.

add_journal_entry

Adds a comment to any object, with optional template parameters.

classify_ticket

Only suggests a type from text - changes nothing.

take_over / accept

Claims tickets. Needs type_name, the configuration item they belong to.

forward

Hands tickets to a role_id or user_id, optionally applying an OLA.

pause

Holds a ticket, optionally stopping the escalation clock (not_escalate_while_paused).

reopen

Reverses a close, with a reason.

return_to_role

Gives one ticket back to its responsible role.

set_deadline

Sets the date the ticket must be handled by.

track_working_time

Books effort, optionally typed (investigation, resolution, …).

transform

Turns tickets into another type - an incident into a service request, say. Rewrites what the record is; fields the target type lacks are lost.

Matrix42 wraps its state machine in these named operations rather than exposing a raw state field, which is what makes them safe to offer: each carries exactly the parameters its transition needs.

Preview, then confirm

Every action previews by default. Called without confirm: true, a write returns the exact request it would send - method, path, body - along with the consequences worth reading, and changes nothing:

{
  "wouldChange": true,
  "applied": false,
  "summary": "Close 1 ticket(s)",
  "request": { "method": "POST", "path": "m42Services/api/ticket/Close", "body": { "…": "…" } },
  "effects": ["No notifications are sent and nothing cascades."],
  "next": "Nothing was changed. Show this to the user, and call again with confirm:true to apply it."
}

That preview is the same plan object the execute path runs, so it can never describe one request and send another. Pass dry_run: true to force a preview even when confirm is set.

Every created ticket also gets an internal journal note recording that it was raised through this server. Creating through the API otherwise leaves none of the trace the web interface leaves, so a human picking the ticket up has no way to tell where it came from. The note is never portal-visible, and if it cannot be written the ticket is still reported as created - losing an audit line must never look like a failed create. Turn it off with M42_AUDIT_NOTE=0, or name the assistant with M42_AGENT_LABEL="Acme Helpdesk Assistant".

Two further defaults exist to prevent the mistakes that matter most in service management:

  • Notification e-mails are off. notify_initiator, notify_users and notify_responsible all default to false; closing a ticket does not mail anyone unless you ask.

  • Journal entries are internal. visible_in_portal defaults to false, so a comment is not published to the requester's self-service portal by accident.

close_related_incidents also defaults to false, since it cascades to other tickets.

Prompts

Reusable templates your client can offer (in Claude Desktop, the prompts menu). Each one encodes the order of operations this server rewards, so a model does not have to rediscover it by failing:

Prompt

For

explore_instance

Getting oriented in an unfamiliar instance

build_query

Turning a question into a validated ASQL query

triage_ticket

Working one ticket end to end, without changing anything

safe_change

Walking a write through preview → confirm

find_endpoint

Locating the right operation before writing integration code

Resources

The written guides are also published as MCP resources, so a client can read them without a tool call and attach one to a conversation up front:

URI

Contents

matrix42://guide/data-model

Matrix42 is one graph, not many modules

matrix42://guide/schema

Data definitions, configuration items, fragments, pickups

matrix42://guide/asql

The ASQL expression language

matrix42://guide/api

REST API conventions: auth, headers, Public vs Product API

The same text is checked in under docs/ so it is readable on GitHub without running anything - start with Matrix42 is one graph, not many modules, which explains why there is no "Licenses" or "SLAs" table and where those records actually live. Those files are generated from the guide modules (npm run docs), and a test fails if they drift.


Security notes

  • The server is a credentialed proxy. Anything the configured account can read through the API, a connected assistant can reach through the tools it is given. Use an account scoped to what the assistant actually needs.

  • Credentials stay local. They are read from the environment, used only for requests to your instance, and never written to logs or returned by any tool.

  • Never commit .env. It is git-ignored; use your client's env block or a secret prompt.

  • M42_ALLOW_INSECURE_TLS disables certificate verification. Use it only for self-signed development instances, never against production.

  • Limit the surface with M42_TOOLS if you only want part of it.


Development

npm install
npm run build        # compile to dist/
npm run typecheck    # tsc --noEmit
npm test             # unit tests (vitest)
npm run docs         # regenerate docs/ from the guide modules
node scripts/smoke.mjs                # end-to-end against a real instance
node scripts/service-desk-smoke.mjs   # service desk, domains and lifecycle verbs

service-desk-smoke.mjs confines its writes to a single ticket it creates itself, and closes it at the end; nothing pre-existing is modified and no notification e-mail is ever requested.

How it fits together

Two modules carry the guarantees the rest of the server relies on: columns.ts means no projection is ever sent that the instance cannot answer, and write-plan.ts means a preview and its request are the same object.

Layout

src/
  index.ts           entry point: config → client → MCP stdio server
  config.ts          environment configuration + validation
  m42-client.ts      authenticated HTTP client (token exchange, caching, TLS)
  discovery.ts       fragment queries + projections for services/operations
  schema.ts          schema listings, detail projections, enum decoding, pickup resolution
  api-overview.ts    the static Matrix42 API guide served by api_overview
  schema-overview.ts the static data-model guide served by schema_overview
  data.ts            record queries, paging, result shaping, ASQL validation
  objects.ts         journal, attachments, saved views, current-user identity
  tickets.ts         write operations and their safety defaults
  ticket-verbs.ts    the ticket lifecycle verbs (take over, forward, pause, reopen, …)
  service-desk.ts    the uniform ticket Search contract and the service-level endpoints
  columns.ts         resolves query columns from the live schema instead of assuming them
  domains.ts         the curated domain registry (assets, contracts, catalog, …)
  domain-guide.ts    the "one graph, not many modules" guide
  asql-guide.ts      the static ASQL guide served by asql_guide
  resources.ts       publishes the guides as MCP resources
  prompts.ts         reusable prompt templates
  deep-links.ts      URLs into the Matrix42 web interface (pure string building)
  write-plan.ts      the request a write would send, as a value - the basis of preview/confirm
  tools/             one module per tool, registered from a small registry

Adding a tool means adding a module under src/tools/ and listing it in src/tools/index.ts; its id then works in M42_TOOLS automatically.


Roadmap

  • Attachment upload and download

  • Approval decisions (approve / reject), which today are read-only

  • Per-user tokens, so "my items" can mean an end user rather than the service account


Contributing

Contributions are very welcome - this is a community project and it gets better with more instances behind it. Matrix42 deployments differ enormously, so a bug report that quotes the exact request and the exact error is worth a lot: it is often the only way to learn that an attribute or an operation behaves differently elsewhere.

Good first contributions:

  • A domain that matters to you but is missing from src/domains.ts.

  • A correction to a guide in src/*-guide.ts / src/*-overview.ts (then run npm run docs).

  • A failing case from your instance, with the request and response, as an issue.

Before opening a pull request:

npm run typecheck && npm test && npm run build

Support

Community support only, through GitHub issues and discussions. There is no SLA, and Matrix42 AG cannot help you with this project - please do not open a ticket with them about it.

Project

Contributing

CONTRIBUTING.md

Code of conduct

CODE_OF_CONDUCT.md

Security policy

SECURITY.md

Changelog

CHANGELOG.md

Releases

GitHub releases

Releases are published from CI when a GitHub Release is published, using npm trusted publishing - no long-lived npm token exists anywhere, and every tarball carries provenance linking it to the commit and workflow run that built it.

Security

Found a vulnerability? Please report it privately rather than in a public issue - see SECURITY.md.

License

MIT © 2026 S&S Technologies GmbH


Disclaimer

This project is an independent, community-maintained integration. It is not affiliated with, endorsed by, sponsored by, or supported by Matrix42 AG. "Matrix42" and any related marks belong to their respective owners and are used here solely to identify the software this project interoperates with. No Matrix42 source code or documentation is redistributed in this repository.

The software is provided "as is", without warranty of any kind. You are responsible for the account you configure it with and for anything an assistant does through it - read Security notes before pointing it at a production instance.

Available Tools

5 tools
data_queryMatrix42 data queryA
Read-only

Read records from the connected Matrix42 instance (read-only). action='asql_guide' explains the ASQL expression language used by 'where' and 'columns' — read it before writing a filter. action='validate_asql' checks an expression against a class and reports the exact error; validating is cheaper than a failed query. action='query' returns rows of one data definition, with typed column metadata, an ASQL 'where' filter, 'columns' projection, 'sort', and paging. action='get_fragment' returns one complete fragment by id; action='get_object' returns a whole object by configuration-item name and object id. action='list_views' lists the instance's saved data queries — curated, named views that already carry a predefined filter — and action='run_view' runs one; prefer a matching view over hand-written ASQL. action='list_journal' returns an object's comment timeline and action='list_attachments' its files. NEVER guess attribute names: read them with schema_discovery(describe_data_definition) before writing 'columns' or 'where', and use get_pickup_values for the valid values of any pickup you filter on.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNo1-based page number (default 1).
sortNoSort expression, e.g. 'CreatedDate DESC'. Pass one whenever you page — without it, page boundaries are not stable.
classNoInternal name of the data definition to read, e.g. 'SPSActivityClassBase'. Required by query, get_fragment and validate_asql.
whereNoASQL filter expression, e.g. "Subject LIKE '%printer%' AND T(SPSCommonClassBase).State.Value = 710".
actionYesWhich data operation to perform.
searchNoFilter saved views by name, description or class (list_views), or free-text search within a view (run_view).
verifyNoFor action='deep_link': resolve the object's real configuration item first, so a dead link is reported rather than handed over. Defaults to true; set false only to build a link for an id this instance cannot resolve.
ci_nameNoConfiguration item internal name, e.g. 'SPSActivityTypeIncident'. Required for action='get_object'.
columnsNoComma-separated ASQL column expressions, e.g. 'ID,Subject,[Expression-ObjectID]'. Use only attribute names reported by schema_discovery(describe_data_definition) — guessed names fail. Aliases are supported ('expr AS Name'). ID is added for you; do NOT request DisplayString (it is returned automatically and cannot be selected explicitly). Omit entirely for Matrix42's default columns.
view_idNoId of a saved data query. Required for action='run_view'.
embeddedNoHide the surrounding navigation, for embedding the page elsewhere.
action_idNoAction or wizard to run, for view_type='action'.
dialog_idNoOpen a specific dialog instead of the default one.
object_idNoObject id — the value of [Expression-ObjectID] on a row. Required for get_object, list_journal and list_attachments.
page_sizeNoRows per page (default 25).
view_typeNoFor action='deep_link': how to open the object. 'preview' (default) is read-only, 'edit' opens the form, 'new' a creation form, 'action' a wizard. Only 'new' works without an object_id.
expressionNoThe ASQL expression to check. Required for action='validate_asql'.
applicationNoUUX application hosting the creation form, e.g. 'ServiceDesk'. Used by link_kind='create'.
fragment_idNoFragment id. Required for action='get_fragment'.
link_view_idNoShow only one page of the dialog, for action='deep_link'.
preset_paramsNoValues to pre-fill a creation form, keyed by data definition then attribute, e.g. {"SPSActivityClassBase":{"Initiator":"<user fragment id>"}}.

TDQS

A4.7/5.0
Behavior5/5

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

Adds rich behavioral context well beyond the readOnlyHint/openWorldHint annotations: ID is auto-added to queries, DisplayString is returned automatically and 'cannot be selected explicitly', 'without [sort], page boundaries are not stable', validation is cheaper than a failed query, and guessed attribute names fail. deep_link's verify parameter behavior is disclosed in the schema, and the description's read-only claim is consistent with readOnlyHint=true. No contradiction.

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?

Long (~400 words) but proportionate to a 10-action, 21-parameter tool; the core read-only purpose is front-loaded and the action enumeration is compact. Every clause earns its place, though it could be tightened into a structured list rather than a dense paragraph.

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?

Very complete for a tool this complex: covers 9 of 10 actions with prerequisites, failure modes ('guessed names fail'), and best-practice warnings, while the query action's return shape ('rows... with typed column metadata') is at least named despite no output schema. The sole gap is action='deep_link', absent from the description; its behavior is partially recovered by the schema's parameter descriptions (verify, view_type, embedded), so the omission is not disabling.

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 100% with already-detailed parameter descriptions (examples for where, enum meanings for view_type, verify's default and opt-out case), so the baseline is 3. The description adds value above that by giving each value of the central 'action' parameter a purpose clause and by stating cross-parameter rules — pass sort whenever you page; never request columns not reported by schema_discovery — that the schema alone does not convey.

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?

Opens with a specific verb and resource — 'Read records from the connected Matrix42 instance (read-only)' — and enumerates its nine named sub-actions (asql_guide, validate_asql, query, get_fragment, get_object, list_views, run_view, list_journal, list_attachments), making the tool's scope unmistakable. The read-only data-access framing implicitly separates it from schema discovery and service operations, so an agent can tell what this tool is for at a glance.

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?

Gives explicit when-to-use guidance with named alternatives: read asql_guide 'before writing a filter', validating 'is cheaper than a failed query', and 'prefer a matching view over hand-written ASQL' for run_view. It also names a sibling tool as a prerequisite — 'NEVER guess attribute names: read them with schema_discovery(describe_data_definition)' and use get_pickup_values for pickup filtering — which properly routes the agent across the toolset.

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

schema_discoveryMatrix42 schema discoveryA
Read-only

Explore the Matrix42 data model of the connected instance (read-only metadata). action='schema_overview' explains how the model fits together (data definitions vs configuration items, fragments, cardinality, pickups) — read this first. action='list_data_definitions' and action='list_configuration_items' find schema objects by 'search' term. action='describe_data_definition' returns a definition's attributes (add include='relations' or 'both' for its relations). action='describe_configuration_item' returns the data definitions an object is composed of, with cardinality and multi-fragment flags. action='get_pickup_values' returns the selectable values of a pickup — either pass 'pickup_class', or 'name' plus 'attribute' to resolve it. Typical flow: schema_overview → list_* (search) → describe_* → get_pickup_values before filtering on a pickup.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoInternal name of the data definition or configuration item to describe (e.g. 'SPSUserClassBase'). Required by the describe_* actions, and usable with get_pickup_values together with 'attribute'.
limitNoMaximum number of listing entries to return (default 100, 0 = no limit). Used by the list_* actions.
actionYesWhich schema question to answer.
searchNoCase-insensitive filter over internal name, display name, and description. Used by the list_* actions.
includeNoFor describe_data_definition: which parts to return. Defaults to 'attributes' because a central definition can have well over a hundred relations.
attributeNoFor get_pickup_values: the pickup attribute on 'name' whose values you want (e.g. name='SPSUserClassBase', attribute='UserType').
pickup_classNoFor get_pickup_values: the pickup class directly, when you already know it from describe_data_definition.
include_pickupsNoFor list_data_definitions: include pickup classes, which are excluded by default because they are numerous and rarely browsed directly.

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already declare readOnlyHint and openWorldHint, and the description reinforces read-only status in the first sentence. It adds valuable behavioral context: list_data_definitions excludes pickups by default, describe_data_definition defaults to attributes because relations can exceed a hundred, and get_pickup_values resolves pickups via two alternative routes. This goes well beyond the annotations.

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

Conciseness5/5

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

The description is dense but perfectly structured: a one-sentence scope statement, a per-action breakdown, and a closing typical flow. Every sentence adds information, and the most important routing guidance ('read this first') is placed early. No filler or redundant restatement 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?

This is a multi-action tool with six distinct operations and eight parameters, and the description covers every action's purpose, the parameters each action consumes, defaults, and a recommended sequence. With no output schema, the description still tells the agent what kind of result each action returns. Nothing needed for correct invocation is missing.

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 coverage is 100%, but the description adds substantial meaning beyond the schema: it explains the purpose of each action, which parameters apply to which action, the default behavior of include, and the two ways to resolve pickup values. The 'read this first' guidance for schema_overview and the typical flow description give parameters operational context the schema alone lacks.

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 opens with a precise statement of what the tool does: 'Explore the Matrix42 data model of the connected instance (read-only metadata).' It then enumerates six concrete action verbs and their resources, making the tool's scope unmistakable and distinguishing it from the data-querying purpose implied by siblings like data_query.

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 gives explicit internal routing: schema_overview should be read first, followed by the typical flow overview → list_* → describe_* → get_pickup_values. It also explains when to use pickup_class versus name plus attribute. It does not explicitly contrast against sibling tools, but the read-only metadata framing and detailed action-level guidance are strong enough to guide selection.

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

server_infoMatrix42 server infoA
Read-only

Report which Matrix42 instance this MCP server is connected to (base URL, authentication mode, response language), which account the credentials authenticate as, and whether the connection works. Use the reported user fragment id to answer "my items" questions. Never returns credentials.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior4/5

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

The description adds meaningful behavioral context beyond the readOnlyHint annotation, notably that it never returns credentials and that it verifies whether the connection works. This reassures an agent about safety and expected operational 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?

The description is concise and front-loaded, stating the primary purpose first, then the practical usage hint, then the safety guarantee. Every sentence contributes useful information without redundancy.

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 zero-parameter read-only informational tool, the description covers what the agent needs: what is reported, how to use a reported value, and a safety boundary. No output schema exists, but the description sufficiently enumerates the expected information categories.

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 accepts no parameters, and schema description coverage is 100%, so there is no parameter documentation burden. The description appropriately focuses on what the tool reports rather than parameter details that do not exist.

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 what the tool does: report connection details for the Matrix42 instance, the authenticated account, and connection status. This distinguishes it from the sibling tools, which involve discovery and data querying, by making the server/account introspection purpose explicit.

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 provides clear context for when the tool is relevant, especially the instruction to use the reported user fragment id for answering 'my items' questions. It does not explicitly list exclusions or compare with sibling tools, but the use case is sufficiently clear for an agent.

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

service_deskMatrix42 service deskA
Read-only

Read the service desk and the business objects around it. action='data_model' explains how Matrix42's modules map onto a handful of base classes — read it first if you are unsure where something lives. action='search_tickets' searches ANY ticket kind (incident, problem, change, task, service request, generic ticket, knowledge article) through one uniform contract. Only subject, category_name and states actually filter — Matrix42 accepts the other parameters and ignores them, so they are refused rather than returning every ticket. To filter on a person, ticket number or asset, use data_query with an ASQL where clause. action='get_ticket' returns one ticket's summary (it takes the OBJECT id — a fragment id answers null), action='sla_for_ticket' the service levels that apply to it, and action='sla_times' applies a service-level duration between two points in time. action='browse' lists a curated domain: assets (SPSAssetClassBase), stock_units (SPSStockKeepingUnitClassBase), contracts (SPSContractClassBase), slas (SVCServiceLevelAgreementClassBase), catalog_services (SPSArticleClassBase), bookings (SVCServiceBookingClassBase), kb_articles (SVMKBArticleClassBase), approvals (SVCApprovalTaskClassBase), imports (GDIEImportClassBase), import_runs (GDIEImportLogClassBase), workflow_instances (PLSLProcessInstanceClassBase), workflow_definitions (PLSLComponentClassBase), applications (SPSApplicationClassBase). action='find' searches ALL of those domains at once for a name — reach for it when you do not know where something lives. It does not cover tickets; search those with search_tickets. Columns are resolved against this instance every time, so fields a module does not install are reported as unavailable rather than failing the call.

ParametersJSON Schema
NameRequiredDescriptionDefault
endNoISO end of the window, for action='sla_times'.
kindNoTicket kind to search. Required for action='search_tickets'.
beginNoISO start of the window, for action='sla_times'.
limitNoMaximum rows to return (default 25).
whereNoAdditional ASQL filter for browse. Use attribute names from schema_discovery(describe_data_definition).
actionYesWhat to do.
domainNoWhich curated domain to list. Required for action='browse'.
searchNoFree-text filter, matched against a domain's searchable fields. Required for action='find'.
statesNoComma-separated state ids to include. Read valid ids with schema_discovery(get_pickup_values).
domainsNoRestrict action='find' to these domains. Defaults to all of them.
subjectNoFilter by subject text.
user_idNoUser fragment id for only_mine — server_info reports the authenticated account's.
asset_idNoNOT APPLIED by Matrix42 — passing it is refused.
durationNoDuration in minutes to apply. Required by action='sla_times'.
only_mineNoRestrict to items related to the user given in user_id.
service_idNoNOT APPLIED by Matrix42 — passing it is refused.
category_nameNoFilter by category NAME (no id needed). One of the three filters that works.
ticket_numberNoNOT APPLIED by Matrix42 — passing it is refused. Filter on TicketNumber with data_query instead.
initiator_nameNoNOT APPLIED by Matrix42 — passing it is refused. Filter on the initiator with data_query instead.
recipient_nameNoNOT APPLIED by Matrix42 — passing it is refused.
ticket_object_idNoTicket OBJECT id, for get_ticket, sla_for_ticket and sla_times.
recipient_role_nameNoNOT APPLIED by Matrix42 — passing it is refused.

TDQS

A4.9/5.0
Behavior5/5

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

Annotations already mark the tool as readOnly and openWorld, and the description reinforces this ('Read the service desk'). It adds substantial operational nuance beyond the annotations: Matrix42 silently ignores certain filter parameters and the tool refuses them, get_ticket answers null for fragment ids, fields absent from a module are reported as unavailable rather than failing, and search_tickets covers all ticket kinds through one contract.

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?

Long but justifiably dense: seven actions, thirteen browse domains, and multiple caveats are packed into a well-organized, front-loaded description. Each sentence carries operational value, from 'read it first if you are unsure' to the closing note about per-instance column resolution. There is no filler.

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 polymorphic read-only tool with 22 parameters and no output schema, the description is remarkably complete. It covers every action, the domain list for browse, the relationship to data_query, the exact filter caveat, id-type semantics for get_ticket, and instance-specific schema resolution. The sibling tools are addressed where relevant, and the absence of an output schema is mitigated by explaining what each action returns or how failures surface.

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 100%, so the baseline is 3; the description builds on that by clarifying which parameters actually do something ('Only subject, category_name and states actually filter'), which parameters are refused, and how action-specific parameters map to actions like sla_times or get_ticket. It does not exhaustively walk through all 22 parameters, but the schema already describes each one, so this is appropriately complementary.

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 opens with a clear 'Read the service desk and the business objects around it' and then enumerates each action with a specific verb and resource: search_tickets, get_ticket, sla_for_ticket, sla_times, browse, find. It explicitly distinguishes find from search_tickets ('It does not cover tickets') and points to data_query for person/ticket-number/asset filtering, so an agent can tell it apart from sibling tools.

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?

The description gives direct routing guidance: read data_model first if unsure where something lives, use find when you do not know where something lives, use search_tickets for tickets, and use data_query with an ASQL where clause to filter on person, ticket number, or asset. It also warns which parameters are ignored/refused, preventing wasted calls.

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

webservice_discoveryMatrix42 web service discoveryA
Read-only

Discover the Matrix42 REST API of the connected instance (read-only metadata). action='api_overview' returns general Matrix42 API conventions (token exchange, the Explicit-Language header, Public vs Product API) — useful for reasoning about the API or writing standalone integration code. action='list_operations' returns operations as {id,name,method,path,service,documentation}; pass 'search' to filter by name/documentation/service or 'service_id' to limit to one service. action='list_services' lists every web service with its documentation. action='describe_operation' with 'operation_id' returns that operation's full contract: HTTP method, path, parameters with types, and return type. Typical flow: api_overview (once) → list_operations(search) → describe_operation(id).

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum number of operations to return (default 200, 0 = no limit). Only used with action='list_operations'.
actionYesWhich discovery step to perform.
searchNoCase-insensitive filter over operation name, documentation, and service name. Only used with action='list_operations'.
service_idNoLimit results to a single web service (id from action='list_services'). Only used with action='list_operations'.
operation_idNoOperation id to describe. Required for action='describe_operation'.

TDQS

A4.7/5.0
Behavior5/5

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

Beyond the readOnlyHint annotation, the description details per-action behavior, including return shapes for list_operations, the nature of api_overview content, and the required inputs for describe_operation. It also clarifies that the tool is metadata-only and references authentication conventions as discoverable content, providing meaningful behavioral context.

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 dense but well-structured, front-loading the core purpose and then systematically covering each action, its parameters, and the typical flow. Every sentence carries actionable information without repetition or filler.

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 multi-action discovery tool with no output schema, the description is exceptionally complete: it defines all actions, their return content, parameter usage, and a recommended call sequence. An agent has enough information to select the right action and parameters for a discovery task.

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 input schema already documents all five parameters with a high coverage level, so the baseline is 3. The description adds value by mapping each parameter to the action it affects, explaining search and service_id filtering semantics, and noting operation_id's requirement for describe_operation.

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 identifies a specific verb ('Discover'), a specific resource ('Matrix42 REST API of the connected instance'), and its read-only metadata nature. It enumerates four distinct actions with concrete outputs, so an agent can understand the tool's scope and distinguish it from data-query or schema-related 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?

The description gives clear context for when this tool is useful: reasoning about the API or writing standalone integration code. It also provides a typical discovery flow, but it does not explicitly name sibling tools or state when not to use it, so it stops short of a full when/when-not comparison.

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. 5 tool updatesv0.1.5
    • First observeddata_query
    • First observedschema_discovery
    • First observedserver_info
    • First observedservice_desk
    • First observedwebservice_discovery

TDQS

A4.7/5.0

Scored across 5 tools

Disambiguation5/5

Each tool maps to a distinct layer: connection info, API metadata, schema metadata, generic data queries, and curated service-desk reads. The potential overlap between data_query and service_desk is explicitly resolved by framing data_query as the ASQL/record-level interface and service_desk as the curated domain interface.

Naming Consistency5/5

All tool names are lowercase snake_case two-word compounds (server_info, webservice_discovery, schema_discovery, data_query, service_desk) with no mixed conventions or vague verbs. The naming pattern is predictable and matches each tool's role in the set.

Tool Count5/5

Five top-level tools is well-scoped for a Matrix42 integration; each tool covers a coherent area and earns its place. The internal actions are many, but grouping them by capability keeps the surface manageable.

Completeness4/5

The read and discovery side is very comprehensive: API conventions, schema exploration, ASQL validation, generic queries, views, journal/attachements, ticket search/SLA, and curated domain browsing all chain together cleanly. The only notable limitation is that the entire server is read-only—no create/update/delete or ticket-lifecycle actions—so agents that need to act on Matrix42 records will dead-end unless this is intentionally a read-only assistant.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Provides AI assistants with read access to ServiceNow instances to aid in building and debugging applications. It enables users to query tables, retrieve specific records, and inspect table schemas using standard ServiceNow encoded query strings.
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI assistants to explore SQL Server schemas, relationships, and execute safe SQL queries with read-only mode by default and optional write control.
    1
    MIT