matrix42-mcp
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@matrix42-mcp@matrix42-mcp find open incidents"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Matrix42 MCP Server
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 --helpThis 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.
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
403because of role/audience restrictions.
Configuration
All configuration is via environment variables.
Variable | Required | Default | Description |
| ✅ | - | Base URL of the instance, e.g. |
| ✅¹ | - | API token; exchanged for an access token automatically |
| ✅¹ | - | Basic-auth alternative to |
|
| Response language, sent as | |
| all | Comma-separated tool ids to expose | |
|
| Set to | |
|
| Set to | |
|
| Mark created tickets with an internal note saying they were raised through this server. Set to | |
|
| How the assistant is named in that note | |
| discovered | Origin of the web interface, for deep links. Discovered from the instance's web shell config when unset. | |
|
| 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-mcpClaude 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.mjsIt 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 idsTools 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 |
| Reports which Matrix42 instance is connected and verifies the credentials work. Never returns credentials. |
| Discovers the REST API. See the actions below. |
| Explores the data model: data definitions, configuration items, attributes, relations, pickup values. |
| Reads records: ASQL queries, saved views, journal entries, attachments, plus an ASQL guide and validator. |
| Searches tickets of any kind, answers service-level questions, and browses assets, contracts, catalog services, bookings, knowledge articles, approvals, imports and workflow instances. |
| Writes - the ticket lifecycle: create, close, take over, forward, pause, reopen, set deadlines, track time, add journal entries. Only present when |
webservice_discovery actions
Action | Parameters | Returns |
| - | General Matrix42 API conventions: token exchange, |
|
| Operations as |
| - | Every web service with its route prefix and documentation. |
|
| 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 |
| - | 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. |
|
| Definitions as |
|
| Items with their main class and member definitions. |
|
| Attributes with decoded datatypes and pickup cross-links. Relations are excluded by default (a central definition can have 150+) - pass |
|
| The definitions an object is composed of, each with its cardinality and a |
|
| The selectable |
Typical flow: schema_overview → list_* with a search term → describe_* → get_pickup_values
before filtering on any pickup attribute.
data_query actions
Action | Parameters | Returns |
| - | The ASQL expression language used by |
|
| Whether an expression is valid, with the exact error (e.g. "does not contain attribute Nope"). Cheaper than a failed query. |
|
| Rows plus typed column metadata, with paging ( |
|
| One complete fragment. |
|
| One whole object (all fragments of a configuration item). |
|
| The instance's saved data queries - curated views that already carry a predefined filter. Prefer a matching view over hand-written ASQL. |
|
| An object's comment/activity timeline. |
|
| The files attached to an object. |
|
| 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_asql → query. 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.
Links into the web interface
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 |
| - | 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. |
|
| Matching tickets. |
|
| One ticket's summary as the service desk sees it. |
|
| The service level agreements that apply, as Matrix42 itself computes them. |
|
| Reaction and solution time state. |
|
| Rows of one curated domain, plus the fields this instance does not have. |
|
| 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 |
| Returns the new object id, which every other action takes directly. |
| Closes by object id, with an optional solution and closing reason. |
| Adds a comment to any object, with optional template |
| Only suggests a type from text - changes nothing. |
| Claims tickets. Needs |
| Hands tickets to a |
| Holds a ticket, optionally stopping the escalation clock ( |
| Reverses a close, with a reason. |
| Gives one ticket back to its responsible role. |
| Sets the date the ticket must be handled by. |
| Books effort, optionally typed ( |
| 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_usersandnotify_responsibleall default tofalse; closing a ticket does not mail anyone unless you ask.Journal entries are internal.
visible_in_portaldefaults tofalse, 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 |
| Getting oriented in an unfamiliar instance |
| Turning a question into a validated ASQL query |
| Working one ticket end to end, without changing anything |
| Walking a write through preview → confirm |
| 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 is one graph, not many modules |
| Data definitions, configuration items, fragments, pickups |
| The ASQL expression language |
| 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'senvblock or a secret prompt.M42_ALLOW_INSECURE_TLSdisables certificate verification. Use it only for self-signed development instances, never against production.Limit the surface with
M42_TOOLSif 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 verbsservice-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 registryAdding 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 runnpm 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 buildSupport
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 | |
Code of conduct | |
Security policy | |
Changelog | |
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 toolsdata_queryMatrix42 data queryARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | 1-based page number (default 1). | |
| sort | No | Sort expression, e.g. 'CreatedDate DESC'. Pass one whenever you page — without it, page boundaries are not stable. | |
| class | No | Internal name of the data definition to read, e.g. 'SPSActivityClassBase'. Required by query, get_fragment and validate_asql. | |
| where | No | ASQL filter expression, e.g. "Subject LIKE '%printer%' AND T(SPSCommonClassBase).State.Value = 710". | |
| action | Yes | Which data operation to perform. | |
| search | No | Filter saved views by name, description or class (list_views), or free-text search within a view (run_view). | |
| verify | No | For 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_name | No | Configuration item internal name, e.g. 'SPSActivityTypeIncident'. Required for action='get_object'. | |
| columns | No | Comma-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_id | No | Id of a saved data query. Required for action='run_view'. | |
| embedded | No | Hide the surrounding navigation, for embedding the page elsewhere. | |
| action_id | No | Action or wizard to run, for view_type='action'. | |
| dialog_id | No | Open a specific dialog instead of the default one. | |
| object_id | No | Object id — the value of [Expression-ObjectID] on a row. Required for get_object, list_journal and list_attachments. | |
| page_size | No | Rows per page (default 25). | |
| view_type | No | For 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. | |
| expression | No | The ASQL expression to check. Required for action='validate_asql'. | |
| application | No | UUX application hosting the creation form, e.g. 'ServiceDesk'. Used by link_kind='create'. | |
| fragment_id | No | Fragment id. Required for action='get_fragment'. | |
| link_view_id | No | Show only one page of the dialog, for action='deep_link'. | |
| preset_params | No | Values to pre-fill a creation form, keyed by data definition then attribute, e.g. {"SPSActivityClassBase":{"Initiator":"<user fragment id>"}}. |
TDQS
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.
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.
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.
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.
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.
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 discoveryARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Internal 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'. | |
| limit | No | Maximum number of listing entries to return (default 100, 0 = no limit). Used by the list_* actions. | |
| action | Yes | Which schema question to answer. | |
| search | No | Case-insensitive filter over internal name, display name, and description. Used by the list_* actions. | |
| include | No | For describe_data_definition: which parts to return. Defaults to 'attributes' because a central definition can have well over a hundred relations. | |
| attribute | No | For get_pickup_values: the pickup attribute on 'name' whose values you want (e.g. name='SPSUserClassBase', attribute='UserType'). | |
| pickup_class | No | For get_pickup_values: the pickup class directly, when you already know it from describe_data_definition. | |
| include_pickups | No | For list_data_definitions: include pickup classes, which are excluded by default because they are numerous and rarely browsed directly. |
TDQS
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.
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.
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.
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.
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.
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 infoARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
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.
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.
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.
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.
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.
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 deskARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| end | No | ISO end of the window, for action='sla_times'. | |
| kind | No | Ticket kind to search. Required for action='search_tickets'. | |
| begin | No | ISO start of the window, for action='sla_times'. | |
| limit | No | Maximum rows to return (default 25). | |
| where | No | Additional ASQL filter for browse. Use attribute names from schema_discovery(describe_data_definition). | |
| action | Yes | What to do. | |
| domain | No | Which curated domain to list. Required for action='browse'. | |
| search | No | Free-text filter, matched against a domain's searchable fields. Required for action='find'. | |
| states | No | Comma-separated state ids to include. Read valid ids with schema_discovery(get_pickup_values). | |
| domains | No | Restrict action='find' to these domains. Defaults to all of them. | |
| subject | No | Filter by subject text. | |
| user_id | No | User fragment id for only_mine — server_info reports the authenticated account's. | |
| asset_id | No | NOT APPLIED by Matrix42 — passing it is refused. | |
| duration | No | Duration in minutes to apply. Required by action='sla_times'. | |
| only_mine | No | Restrict to items related to the user given in user_id. | |
| service_id | No | NOT APPLIED by Matrix42 — passing it is refused. | |
| category_name | No | Filter by category NAME (no id needed). One of the three filters that works. | |
| ticket_number | No | NOT APPLIED by Matrix42 — passing it is refused. Filter on TicketNumber with data_query instead. | |
| initiator_name | No | NOT APPLIED by Matrix42 — passing it is refused. Filter on the initiator with data_query instead. | |
| recipient_name | No | NOT APPLIED by Matrix42 — passing it is refused. | |
| ticket_object_id | No | Ticket OBJECT id, for get_ticket, sla_for_ticket and sla_times. | |
| recipient_role_name | No | NOT APPLIED by Matrix42 — passing it is refused. |
TDQS
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.
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.
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.
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.
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.
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 discoveryARead-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).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of operations to return (default 200, 0 = no limit). Only used with action='list_operations'. | |
| action | Yes | Which discovery step to perform. | |
| search | No | Case-insensitive filter over operation name, documentation, and service name. Only used with action='list_operations'. | |
| service_id | No | Limit results to a single web service (id from action='list_services'). Only used with action='list_operations'. | |
| operation_id | No | Operation id to describe. Required for action='describe_operation'. |
TDQS
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.
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.
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.
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.
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.
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.
5 tool updates
v0.1.5- First observed
data_query - First observed
schema_discovery - First observed
server_info - First observed
service_desk - First observed
webservice_discovery
TDQS
Scored across 5 tools
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.
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.
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.
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
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
Sandbox workspace tools: search, file read, DB queries, integrations. Returns synthetic data.
Query your org's data in natural language — read-only MCP access to SQL, NoSQL, files & warehouses.
Safe, read-only Postgres and MySQL access for AI agents. Audit log + column-level controls.
Read-only MCP access to a documented IT fleet: state, changes, posture. 15 tools.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceProvides 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.-
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to securely query VAST Data databases for schema, metadata, and sample data via read-only SQL and MCP resources.MIT
- FlicenseCqualityDmaintenanceEnables AI assistants to analyze and query SQL Server databases, including schema discovery, health checks, and data retrieval.10-
- AlicenseNot gradedqualityCmaintenanceEnables AI assistants to explore SQL Server schemas, relationships, and execute safe SQL queries with read-only mode by default and optional write control.1MIT