VOOZH about

URL: https://glama.ai/mcp/servers/madosh/MCP-ITSM

โ‡ฑ MCP FOR ITSM by madosh | Glama


MCP ITSM

Unified IT Service Management over the Model Context Protocol โ€” create, track, and resolve tickets across ServiceNow, Jira, Zendesk, Ivanti Neurons, and Cherwell from any MCP-compatible LLM client.

๐Ÿ‘ MCP Spec
๐Ÿ‘ SDK
๐Ÿ‘ Node
๐Ÿ‘ License
๐Ÿ‘ Smithery


Table of Contents


Related MCP server: MCP-openproject

Overview

MCP ITSM exposes a standardised set of MCP tools, resources, and prompts so that any LLM client (Claude, Cursor, custom agents) can manage IT tickets without knowing the underlying ITSM system's API.

What it is:

Layer

What's here

index.js

MCP server โ€” 7 tools, 4 resources, 3 prompts over stdio

backend/

Express REST API that bridges HTTP clients to the MCP server via the official SDK Client

frontend/

React 18 web app โ€” Ticket Manager UI + live Monitoring Dashboard

Why it matters:
Instead of writing separate integrations for ServiceNow, Jira, Zendesk, Ivanti, and Cherwell, an LLM calls create_ticket once and the correct system receives it. Every tool carries safety annotations (readOnlyHint, destructiveHint) so the model knows what it can call without risk.


Architecture

graph TB
 subgraph "MCP Clients"
 Claude["Claude / Cursor / Agent"]
 Inspector["MCP Inspector"]
 UI["React Frontend :3000"]
 end

 subgraph "Transport"
 Stdio["StdioServerTransport\n(Smithery / Inspector)"]
 Bridge["Express API :5000\nSDK Client + StdioClientTransport"]
 end

 subgraph "MCP Server โ€” index.js v3.0.0"
 McpSrv["McpServer\nspec 2025-11-25"]
 Tools["7 Tools\nZod ยท annotated"]
 Resources["4 Resources\nKB articles ยท Tickets"]
 Prompts["3 Prompts\nIncident ยท Status ยท KB-assist"]
 Store["In-Memory Store\nTickets & KB articles"]
 end

 subgraph "Backend Services"
 Auth["JWT Auth"]
 Metrics["Metrics Store"]
 Mongo[("MongoDB")]
 end

 Claude -->|stdio| Stdio
 Inspector -->|stdio| Stdio
 UI -->|HTTP + JWT| Bridge

 Stdio --> McpSrv
 Bridge -->|"MCP SDK Client\n(proper handshake)"| McpSrv

 McpSrv --> Tools
 McpSrv --> Resources
 McpSrv --> Prompts
 Tools <--> Store
 Resources --> Store

 Bridge --> Auth
 Bridge --> Metrics
 Auth --> Mongo

Request flow โ€” browser tool call:

sequenceDiagram
 participant U as User
 participant UI as React UI :3000
 participant API as Express API :5000
 participant C as MCP SDK Client
 participant MCP as McpServer index.js

 U->>UI: Submit form
 UI->>API: POST /api/mcp/tools/call (JWT)
 API->>C: client.callTool(name, args)
 Note over C: StdioClientTransport
 C->>MCP: tools/call (MCP protocol)
 Note over MCP: Zod validates input
 MCP->>MCP: tool handler + in-memory store
 MCP-->>C: CallToolResult
 C-->>API: result
 API->>API: recordCall() โ†’ metrics
 API-->>UI: { success, data, _meta }
 UI->>U: Show result

Quick Start

Prerequisites

  • Node.js โ‰ฅ 18

  • MongoDB (local or Atlas โ€” required by the backend)

  • Optional: Smithery CLI for cloud deployment

1 โ€” Install dependencies

# Root (MCP server)
npm install

# Backend API
cd backend && npm install && cd ..

# Frontend
cd frontend && npm install && cd ..

2 โ€” Configure environment

cp .env.example .env # root โ€” API key for Smithery / MCP auth
cp backend/.env.example backend/.env # backend โ€” Mongo URI, JWT secret, ITSM creds

Minimum required for local dev (edit backend/.env):

MONGODB_URI=mongodb://localhost:27017/mcp-itsm
JWT_SECRET=change-me-in-production

3 โ€” Start all services

Open three terminals:

# Terminal 1 โ€” MCP server (stdio)
npm start

# Terminal 2 โ€” Backend API
cd backend && npm start # http://localhost:5000

# Terminal 3 โ€” Frontend
cd frontend && npm start # http://localhost:3000
flowchart LR
 T1["Terminal 1\nnpm start\nMCP server on stdio"]
 T2["Terminal 2\ncd backend\nnpm start :5000"]
 T3["Terminal 3\ncd frontend\nnpm start :3000"]
 UI["localhost:3000\nTicket Manager\nMonitor Dashboard"]

 T1 -->|"SDK Client\nStdioClientTransport"| T2
 T2 -->|"HTTP + JWT"| T3
 T3 --> UI

Access points

URL

What

http://localhost:3000

React web app

http://localhost:3000/mcp-tickets

MCP Ticket Manager

http://localhost:3000/mcp-monitor

Live Monitoring Dashboard

http://localhost:5000/health

Backend health check

http://localhost:5000/api/mcp/health

MCP server connectivity

http://localhost:5000/api/mcp/metrics

Tool-call metrics (auth required)


Project Structure

mcp-itsm/
โ”œโ”€โ”€ index.js # MCP server (McpServer, Zod, stdio)
โ”œโ”€โ”€ tools.json # Static tool catalogue for Smithery browser
โ”œโ”€โ”€ smithery.yaml # Smithery deployment config
โ”œโ”€โ”€ package.json # Root deps: @modelcontextprotocol/sdk, zod
โ”œโ”€โ”€ .env.example # Root env template
โ”‚
โ”œโ”€โ”€ backend/
โ”‚ โ”œโ”€โ”€ package.json # Express, Mongoose, JWT, MCP SDK Client
โ”‚ โ”œโ”€โ”€ .env.example # Backend env template
โ”‚ โ””โ”€โ”€ src/
โ”‚ โ”œโ”€โ”€ index.js # Express app bootstrap
โ”‚ โ”œโ”€โ”€ config/config.js # Env-driven configuration
โ”‚ โ”œโ”€โ”€ routes/
โ”‚ โ”‚ โ”œโ”€โ”€ mcp.routes.js # MCP bridge + metrics endpoints
โ”‚ โ”‚ โ”œโ”€โ”€ auth.routes.js
โ”‚ โ”‚ โ”œโ”€โ”€ context.routes.js
โ”‚ โ”‚ โ”œโ”€โ”€ integration.routes.js
โ”‚ โ”‚ โ””โ”€โ”€ user.routes.js
โ”‚ โ”œโ”€โ”€ middleware/
โ”‚ โ”‚ โ”œโ”€โ”€ auth.middleware.js
โ”‚ โ”‚ โ””โ”€โ”€ validation.middleware.js
โ”‚ โ”œโ”€โ”€ models/
โ”‚ โ”œโ”€โ”€ validators/
โ”‚ โ””โ”€โ”€ utils/logger.js
โ”‚
โ”œโ”€โ”€ frontend/
โ”‚ โ”œโ”€โ”€ package.json # React 18, Bootstrap, react-router-dom
โ”‚ โ””โ”€โ”€ src/
โ”‚ โ”œโ”€โ”€ App.js
โ”‚ โ”œโ”€โ”€ pages/
โ”‚ โ”‚ โ”œโ”€โ”€ MCPTicketManager.js # Ticket CRUD UI
โ”‚ โ”‚ โ”œโ”€โ”€ MCPMonitorDashboard.js # Live monitoring (polls every 10s)
โ”‚ โ”‚ โ”œโ”€โ”€ Dashboard.js
โ”‚ โ”‚ โ”œโ”€โ”€ LLMChatClient.js
โ”‚ โ”‚ โ””โ”€โ”€ ...
โ”‚ โ”œโ”€โ”€ services/
โ”‚ โ”‚ โ”œโ”€โ”€ mcpService.js # HTTP client for MCP tool calls
โ”‚ โ”‚ โ””โ”€โ”€ api.js # Axios instance with JWT interceptor
โ”‚ โ””โ”€โ”€ components/
โ”‚ โ”œโ”€โ”€ Header.js
โ”‚ โ””โ”€โ”€ ...
โ”‚
โ””โ”€โ”€ docs/
 โ”œโ”€โ”€ api-documentation.md
 โ”œโ”€โ”€ mcp_relationship.md
 โ””โ”€โ”€ llm_enabled_tickets.md

MCP Tools

All 7 tools are registered via McpServer.tool() with Zod input schemas and safety annotations. LLM clients use the annotations to decide whether to call a tool without user confirmation.

Tool

Title

Read-only

Idempotent

Required params

create_ticket

Create Ticket

โ€”

โ€”

title, description

get_ticket

Get Ticket

โœ“

โœ“

ticket_id

update_ticket

Update Ticket

โ€”

โ€”

ticket_id

list_tickets

List Tickets

โœ“

โœ“

โ€”

assign_ticket

Assign Ticket

โ€”

โœ“

ticket_id, user_id

add_comment

Add Comment

โ€”

โ€”

ticket_id, comment

search_knowledge_base

Search KB

โœ“

โœ“

query

Supported systems (via the optional system parameter): servicenow ยท jira ยท zendesk ยท ivanti_neurons ยท cherwell (default: jira)

graph LR
 subgraph RO["Read-only โ€” safe to call freely"]
 GT["get_ticket\nreadOnly ยท idempotent"]
 LT["list_tickets\nreadOnly ยท idempotent"]
 SK["search_knowledge_base\nreadOnly ยท idempotent"]
 end
 subgraph WR["Write โ€” require user intent"]
 CT["create_ticket\nwrite"]
 UT["update_ticket\nwrite"]
 AT["assign_ticket\nwrite ยท idempotent"]
 AC["add_comment\nwrite"]
 end
 style RO fill:#f0fdf4,stroke:#86efac
 style WR fill:#fff1f2,stroke:#fecdd3

Example โ€” create a ticket

// Tool call
{
 "name": "create_ticket",
 "arguments": {
 "title": "VPN not connecting after Windows update",
 "description": "Since the KB5034441 update, VPN client fails to authenticate on first attempt.",
 "priority": "high",
 "system": "jira"
 }
}

// Response
{
 "success": true,
 "ticket": {
 "id": "JIRA-1000",
 "title": "VPN not connecting after Windows update",
 "system": "jira",
 "status": "open",
 "priority": "high",
 "url": "https://example.com/jira/tickets/JIRA-1000"
 }
}

MCP Resources

Resources expose live data that LLM clients can read without a tool call.

URI

Name

Description

kb://articles

kb-articles

All knowledge base articles (JSON)

kb://articles/{id}

kb-article

Single KB article by ID (e.g. KB-001)

itsm://tickets/open

open-tickets

All currently open tickets (live)

itsm://tickets/{ticketId}

ticket

Single ticket by ID (e.g. JIRA-1000)

graph LR
 McpSrv["McpServer"]
 McpSrv -->|"static\nkb://articles"| KBAll["kb-articles\nAll KB articles as JSON"]
 McpSrv -->|"template\nkb://articles/{id}"| KBOne["kb-article\nSingle article by ID"]
 McpSrv -->|"static\nitsm://tickets/open"| TOpen["open-tickets\nLive filtered view"]
 McpSrv -->|"template\nitsm://tickets/{id}"| TOne["ticket\nSingle ticket by ID"]
 style McpSrv fill:#f0fdf4,stroke:#86efac

MCP Prompts

Prompts are guided message templates that clients present to users before a tool call sequence.

Name

Description

Arguments

create-incident-ticket

P1/P2 incident ticket template

title (req), system, affected_service

ticket-status-report

Structured queue summary

filter_status

kb-search-assist

Search KB before creating a ticket

issue_description (req)

sequenceDiagram
 participant U as User
 participant C as MCP Client
 participant MCP as McpServer

 U->>C: "My printer won't install"
 C->>MCP: prompts/get kb-search-assist
 MCP-->>C: message template
 C->>MCP: tools/call search_knowledge_base
 MCP-->>C: KB-005 Printer setup guide
 C->>U: Show article โ€” no ticket needed
 Note over C,U: Only escalates to create_ticket if no article resolves it

Configuration

Root .env (MCP server + Smithery)

# API key used when running via Smithery (injected as API_KEY env var)
API_KEY=your-smithery-api-key

Backend backend/.env

# Server
PORT=5000
NODE_ENV=development

# Database
MONGODB_URI=mongodb://localhost:27017/mcp-itsm

# Auth
JWT_SECRET=change-me-to-a-long-random-string
JWT_EXPIRES_IN=1d

# ITSM integrations (all optional โ€” only needed for live system calls)
SERVICENOW_BASE_URL=https://your-instance.service-now.com
SERVICENOW_USERNAME=admin
SERVICENOW_PASSWORD=

JIRA_BASE_URL=https://your-org.atlassian.net
JIRA_EMAIL=you@example.com
JIRA_API_TOKEN=

ZENDESK_BASE_URL=https://your-org.zendesk.com
ZENDESK_USERNAME=you@example.com
ZENDESK_TOKEN=

IVANTI_BASE_URL=https://your-instance.ivanti.com
IVANTI_CLIENT_ID=
IVANTI_CLIENT_SECRET=

CHERWELL_BASE_URL=https://your-instance.cherwell.com
CHERWELL_CLIENT_ID=
CHERWELL_USERNAME=
CHERWELL_PASSWORD=

# Logging
LOG_LEVEL=info

Monitoring Dashboard

The frontend includes a live monitoring dashboard at /mcp-monitor that polls the backend every 10 seconds.

What it shows:

  • Server connected / disconnected status with uptime

  • Total calls, success rate, failed call count

  • Per-tool call statistics with average latency badges

  • Available tools with annotation labels (read-only, write, idempotent)

  • Registered resources and prompts

  • Live activity log of the last 20 tool calls

The data is sourced from the in-memory metrics store in backend/src/routes/mcp.routes.js and reset on backend restart.

flowchart TD
 DB["React Dashboard\n/mcp-monitor\npoll every 10 s"]
 DB -->|"GET /api/mcp/health"| H["connected ยท uptimeSeconds"]
 DB -->|"GET /api/mcp/metrics"| M["totalCalls ยท successRate\ntoolStats ยท recentCalls"]
 DB -->|"GET /api/mcp/tools/list"| T["tool names + annotations"]
 DB -->|"GET /api/mcp/resources/list"| R["resource URIs"]
 DB -->|"GET /api/mcp/prompts/list"| P["prompt names"]

API Reference

All /api/mcp/* endpoints require a valid JWT in the Authorization: Bearer <token> header.

Method

Path

Description

GET

/api/mcp/health

MCP server connectivity + backend uptime

GET

/api/mcp/metrics

Tool-call metrics (counts, latency, recent calls)

GET

/api/mcp/tools/list

List all registered tools with schemas + annotations

POST

/api/mcp/tools/call

Call a tool โ€” body: { name, arguments }

GET

/api/mcp/resources/list

List registered MCP resources

GET

/api/mcp/prompts/list

List registered MCP prompts

Tool call example (curl)

# Authenticate first
TOKEN=$(curl -s -X POST http://localhost:5000/api/auth/login \
 -H "Content-Type: application/json" \
 -d '{"email":"admin@example.com","password":"password"}' | jq -r '.token')

# Call a tool
curl -X POST http://localhost:5000/api/mcp/tools/call \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -d '{
 "name": "search_knowledge_base",
 "arguments": { "query": "vpn", "limit": 3 }
 }'

Smithery Deployment

The server is published at @madosh/mcp-itsm on Smithery.

flowchart LR
 Dev["Developer\nnpm publish via\nsmithery publish"]
 Smithery["Smithery Cloud\nDocker container\nenv API_KEY injected"]
 MCPSrv["McpServer v3.0.0\nnpm start โ†’ stdio"]
 Client["Claude / Cursor\nany MCP client"]

 Dev -->|"smithery.yaml\ntools.json"| Smithery
 Smithery -->|"spawn"| MCPSrv
 Client -->|"MCP protocol\nstdio"| Smithery
 Smithery <-->|"proxy"| MCPSrv

Install via Smithery CLI

npx -y @smithery/cli install @madosh/mcp-itsm --client claude

Manual Smithery deploy

npm install -g @smithery/cli
smithery login
smithery publish

The smithery.yaml configuration:

startCommand:
 type: stdio
 configSchema:
 type: object
 required: [apiKey]
 properties:
 apiKey:
 type: string
 commandFunction: |-
 (config) => ({ command: 'npm', args: ['start'], env: { API_KEY: config.apiKey } })
tools:
 path: ./tools.json

Use with Claude Desktop

Add to claude_desktop_config.json:

{
 "mcpServers": {
 "mcp-itsm": {
 "command": "node",
 "args": ["/absolute/path/to/mcp-itsm/index.js"],
 "env": { "API_KEY": "your-key" }
 }
 }
}

Debug with MCP Inspector

npm run debug-mcp
# Opens MCP Inspector at http://localhost:5173

Development

Available scripts

# Root
npm start # Start MCP server on stdio
npm run debug-mcp # Start with MCP Inspector attached

# Backend
cd backend
npm start # Production
npm run dev # Development (nodemon hot-reload)
npm test # Jest test suite

# Frontend
cd frontend
npm start # Dev server on :3000
npm run build # Production build

Tech stack

Layer

Technologies

MCP Server

Node.js 18+, @modelcontextprotocol/sdk 1.28.0, Zod 3.23

Backend

Express 4, Mongoose 7, JWT, Helmet, Winston

Frontend

React 18, React Router 6, Bootstrap 5

MCP Spec

2025-11-25

Deployment

Smithery (stdio), Docker

Running with Docker

docker build -t mcp-itsm .
docker run -e API_KEY=your-key mcp-itsm

Contributing

Contributions are welcome. Please:

  1. Fork the repository

  2. Create a feature branch (git checkout -b feat/my-feature)

  3. Commit your changes (git commit -m 'feat: add my feature')

  4. Push to the branch (git push origin feat/my-feature)

  5. Open a Pull Request

Roadmap

  • OAuth 2.1 / OIDC authorization for external clients

  • Elicitation โ€” server-initiated mid-call user prompts

  • Experimental Tasks โ€” durable async ticket workflows

  • Live ITSM system adapters (ServiceNow, Jira, Zendesk)

  • outputSchema / structuredContent on all tools

graph LR
 subgraph Done["Shipped in v3.0.0"]
 D1["SDK 1.28.0 + Zod"]
 D2["McpServer API"]
 D3["Tool annotations"]
 D4["Resources + Prompts"]
 D5["SDK Client transport"]
 D6["Metrics + Dashboard"]
 end
 subgraph Next["Next"]
 N1["OAuth 2.1 / OIDC"]
 N2["Elicitation"]
 N3["Tasks API"]
 N4["Live ITSM adapters"]
 end
 style Done fill:#f0fdf4,stroke:#86efac
 style Next fill:#eff6ff,stroke:#bfdbfe

License

MIT โ€” see LICENSE for details.


Resources

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/madosh/MCP-ITSM'

If you have feedback or need assistance with the MCP directory API, please join our Discord server