FS_MCP_thin

FS_MCP_thin

A read-only MCP server that connects AI assistants to Freshservice Service Desk for ticket triage, asset analysis, and support history summarization.

Category
Visit Server

README

FS_MCP_thin πŸš€

MCP Freshservice

A powerful, read-only Model Context Protocol (MCP) server that bridges the gap between your AI assistant (like Claude) and your Freshservice Service Desk. Empower your AI with deep context to triage incidents, analyze asset distribution, and summarize support history.


✨ Features

  • 🎫 Ticket Intelligence – Deep dive into tickets, conversations, private notes, and service request items.
  • πŸ“š Knowledge Integration – Search and retrieve the full content of your solution articles.
  • πŸ”§ Problem Analysis – Inspect root-cause investigation records.
  • πŸ“¦ Inventory Visibility – Browse and drill down into Assets (Hardware) and Software inventory.
  • πŸ‘€ Identity Context – Lookup Requesters and Agents, and view their specific ticket/asset history.
  • ⏱️ Governance Context – Access SLA policies, business hours, and org structure as standing context.
  • πŸ’¬ Canned Success – Use your curated response templates to draft high-quality replies.
  • πŸͺΆ Token-Efficient – Responses are shaped (field-projected, HTML-stripped, compacted) before they reach the model, cutting context bloat 5-10x on list/detail calls. See Response Shaping.

πŸ›  Prerequisites

  • Node.js: Version 18.x or higher.
  • Freshservice: An active account with API access enabled.
  • API Key: Found in your Profile Settings β†’ API Key.

πŸš€ Quick Start

1. Installation

# Clone or download the repository
cd FS_MCP_thin

# Install dependencies
npm install

# Setup environment variables
cp .env.example .env

2. Configuration

The server needs exactly two environment variables. Both are required β€” if either is missing the server exits immediately on startup with an error.

Variable What it is Where to get it
FRESHSERVICE_DOMAIN Your Freshservice URL The host in your browser, e.g. acme.freshservice.com.
FRESHSERVICE_API_KEY Your personal API key Freshservice β†’ avatar β†’ Profile Settings β†’ API Key (right sidebar).

Domain format: supply just the host (acme.freshservice.com). A full URL (https://acme.freshservice.com) also works β€” the client adds https:// only if no protocol is present. Do not include a trailing slash or path.

How auth works: Freshservice uses HTTP Basic auth with the API key as the username and a dummy password. The server handles this for you β€” you only ever supply the raw key.

Edit the .env file with your details:

FRESHSERVICE_DOMAIN=acme.freshservice.com
FRESHSERVICE_API_KEY=your_api_key_here

.env is git-ignored. Your credentials never leave your machine β€” see Security & Privacy.

3. Integration with Claude Desktop

Add this snippet to your claude_desktop_config.json. The env block here is an alternative to a .env file β€” when Claude Desktop launches the server it injects these, so you don't need both. (If both exist, the values in env take precedence.)

{
  "mcpServers": {
    "freshservice": {
      "command": "node",
      "args": ["C:\\path\\to\\FS_MCP_thin\\src\\index.js"],
      "env": {
        "FRESHSERVICE_DOMAIN": "acme.freshservice.com",
        "FRESHSERVICE_API_KEY": "your_api_key_here"
      }
    }
  }
}

Use the absolute path to src/index.js. On Windows, escape backslashes (\\) as shown.

Troubleshooting credentials

Symptom Likely cause
Server exits with FRESHSERVICE_DOMAIN and FRESHSERVICE_API_KEY ... are required One or both env vars are unset (typo, wrong key name, or .env not loaded).
401 Unauthorized on every call API key is wrong, revoked, or copied with surrounding whitespace.
403 Forbidden on specific tools (assets, problems, catalog) Your account's role or plan tier doesn't grant access to that resource β€” not a config bug.
404 Not Found Wrong domain, or the record ID doesn't exist.
429 Too Many Requests Rate limit hit. Limits are per-plan; the server surfaces the error but does not auto-retry.

πŸ“ Project Structure

FS_MCP_thin/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ index.js              # MCP server entry point β€” registers all tools,
β”‚   β”‚                         #   resources, and prompts; wires responses through shape.js
β”‚   β”œβ”€β”€ freshservice.js       # FreshserviceClient β€” thin axios wrapper over the
β”‚   β”‚                         #   Freshservice v2 REST API (auth, requests, error mapping)
β”‚   β”œβ”€β”€ shape.js              # Token-economy engine β€” projects/strips/compacts responses
β”‚   β”œβ”€β”€ shape.config.js       # Declarative per-domain field/shaping rules (edit this to tune output)
β”‚   β”œβ”€β”€ index.test.js         # Tests for tool registration & handler behavior
β”‚   β”œβ”€β”€ freshservice.test.js  # Tests for the API client
β”‚   └── shape.test.js         # Tests for the shaping engine + config
β”œβ”€β”€ eslint.config.js          # ESLint flat config (Node + Jest, recommended rules)
β”œβ”€β”€ tsconfig.json             # TypeScript config for `checkJs` type-checking
β”œβ”€β”€ .env.example              # Template for required environment variables
β”œβ”€β”€ .gitignore                # Ignores node_modules/ and .env (credentials)
β”œβ”€β”€ package.json              # Dependencies, scripts, bin entry
└── README.md

Data flow: index.js (MCP request) β†’ freshservice.js (API call) β†’ shape.js + shape.config.js (trim response) β†’ back to the AI assistant.

Where to make changes:

  • Add/modify a tool, resource, or prompt β†’ src/index.js
  • Add/modify a Freshservice API call β†’ src/freshservice.js
  • Change what fields the model sees β†’ src/shape.config.js (no code changes needed)

🧰 Available Tools

🎫 Tickets & Conversations

Tool Purpose
search_tickets Flexible search using status, priority, or subject.
list_open_tickets List open tickets (status:2) with pagination.
get_ticket Curated detail view of a ticket (key fields + HTML-stripped body).
get_ticket_conversations Complete thread of public and private messages.
get_ticket_notes Isolates private internal notes for audit/context.
get_service_request_items Views quantity and custom fields for SR items.

πŸ“š Knowledge Base & Problems

Tool Purpose
search_kb Find articles by keywords.
get_kb_article Retrieve the full article body (Markdown/HTML).
list_problems Get a list of recent Problem records.
get_problem Detailed view of a root cause investigation.

πŸ“¦ Assets & Software

Tool Purpose
list_assets Browse the CI (Configuration Item) inventory.
get_asset Deep dive into a specific piece of hardware.
list_software See software installations and licenses.

?? Service Catalog & Responses

Tool Purpose
list_service_catalog_items List items available in the service catalog.
get_service_catalog_item Retrieve details of a specific service catalog item.
list_canned_responses List canned response templates.

πŸ‘€ Identity & History

Tool Purpose
search_requesters Find users by name or email.
get_requester Detailed profile of a user.
get_requester_tickets Historical view of all tickets for a specific user.
get_requester_assets List of hardware currently assigned to a user.
search_agents Find support staff members.
get_agent / get_agent_group Inspect specific agents or support teams.

πŸ“– Available Resources (Standing Context)

Resources can be attached to a conversation to provide the AI with constant reference data without needing a tool call.

URI Content
freshservice://departments Your organizational hierarchy.
freshservice://ticket-fields The schema for custom ticket fields and their values.
freshservice://agent-groups Valid routing destinations (support teams).
freshservice://sla-policies Your response and resolution time targets.
freshservice://business-hours Operation schedules for various teams.

πŸͺ„ Available Prompts (Workflows)

Prompt Scenario
triage_ticket Input: Ticket ID. Output: A comprehensive assessment including history, SR items, and suggested KB articles.
summarize_ticket Input: Ticket ID. Output: A concise executive summary perfect for handoffs or manager reviews.
draft_reply Input: Ticket ID. Output: A professional draft reply incorporating KB solutions and empathy.
sla_check Input: Ticket ID. Output: An analysis of breach risk based on business hours and policies.

πŸ” Search Syntax Reference

The search_tickets tool supports the Freshservice Filter API syntax:

  • Status Codes: 2: Open, 3: Pending, 4: Resolved, 5: Closed.
  • Priority Codes: 1: Low, 2: Medium, 3: High, 4: Urgent.

Examples for AI:

  • "status:2 AND priority:4" β†’ Show me urgent open tickets.
  • "created_at:>'2024-01-01'" β†’ Show me tickets from this year.
  • "type:'Incident'" β†’ Filter for incidents only.

πŸͺΆ Response Shaping (Token Economy)

Freshservice API responses are verbose β€” a single ticket carries 40-60 fields (many null), HTML bodies, and internal metadata the model never needs. To avoid bloating the AI's context window, tool and resource responses pass through a shaping layer before they're returned. Most are field-projected and HTML-stripped; a few (e.g. service-request items, whose custom_fields hold the request's actual answers) are compacted but deliberately kept whole.

What it does:

  • Compact JSON – no pretty-print whitespace (~15-30% saving on every call).
  • Field projection – list/search tools return lean summary rows (e.g. a ticket β†’ id, subject, status, priority, requester_id, group_id, timestamps); detail tools (get_ticket, get_asset, …) return a curated, richer set.
  • HTML stripping – descriptions, conversation bodies, and articles are converted from HTML to plain text (description β†’ description_text), then truncated if very long.
  • Noise removal – null/empty fields and empty custom-field entries are dropped; attachments are reduced to filenames.
  • Defensive fallback – if a response doesn't match the expected shape, it passes through compacted but otherwise untouched (never mangled).

Summary-then-drill-down: list tools intentionally return summaries. When the model needs everything about one record, it calls the matching get_* tool. This keeps broad queries cheap.

Tuning what the model sees

All shaping rules are declarative and live in one file β€” src/shape.config.js. The engine (src/shape.js) contains no per-domain logic, so adjusting output requires no code changes.

Each domain defines a list (summary) and/or detail profile:

tickets: {
  container: 'tickets',   // array key for list responses
  item: 'ticket',         // object key for single-record responses
  list:   { fields: ['id', 'subject', 'status', 'priority', /* … */] },
  detail: {
    fields:  ['id', 'subject', 'status', /* …more… */],
    text:    [{ from: ['description_text', 'description'], to: 'description_text', max: 2000 }],
    objects: ['custom_fields'],   // kept, but null/empty entries dropped
  },
}
Profile key Effect
fields Whitelist of keys to keep (present + non-empty only).
text Take the first available from field, strip HTML, truncate to max, store under to.
objects Custom-field-style objects to keep but compact (drop null/empty).
names Reduce an array of { name, … } objects to an array of names (e.g. attachments).

To add a field to a tool's output, append it to that domain's fields array. To expose more/less body text, change max. That's the whole workflow.

Note: the field names in shape.config.js are mapped to the Freshservice v2 API. If your instance relies on a field that isn't surfaced, add it to the relevant fields array β€” it's a one-line change.


⚑ Performance & Reliability

The Freshservice client (src/freshservice.js) includes several measures to stay fast and resilient under real-world conditions:

  • Request timeout – every request times out after 10s rather than hanging indefinitely on a stalled connection.
  • Automatic retry with backoff – transient failures (429 rate limits, 5xx, network/timeout errors) are retried up to 3 times with exponential backoff. A 429's Retry-After header is honored when present. Non-transient errors (401, 403, 404) are not retried.
  • Caching of static data – near-static reference endpoints (departments, ticket/requester fields, SLA policies, business hours, agent groups) are cached in memory for 10 minutes, so the AI's repeated context-gathering doesn't re-hit the API. Failed lookups are never cached.
  • Concurrent pagination – tools that aggregate every page (list_canned_responses, list_service_catalog_items) fetch page 1, then pull the remaining pages in bounded-concurrency batches (per_page=100, 5 pages at a time) instead of one slow page at a time β€” turning ~10 sequential round-trips into 2-3 parallel batches.

These are tuned by constants at the top of src/freshservice.js (STATIC_TTL_MS, REQUEST_TIMEOUT_MS, MAX_RETRIES).


πŸ§ͺ Development

Command What it does
npm start Run the MCP server on stdio.
npm test Run the Jest test suite.
npm run lint Lint with ESLint (flat config, eslint:recommended + Node/Jest globals).
npm run lint:fix Lint and auto-fix where possible.
npm run typecheck Type-check the JS via TypeScript in checkJs mode (no emit).
npm run check Run lint + typecheck + tests together (use before committing).

Type-checking uses TypeScript's checkJs against the application code (tsconfig.json). It catches real errors β€” e.g. wrong API shapes or SDK misuse β€” without requiring the code to be migrated to TypeScript. Test files are excluded from tsc (their Jest mocks are validated by the test runner, not the type-checker). Implicit-any is allowed, so the checker surfaces genuine type errors rather than annotation noise.


πŸ”’ Security & Privacy

  1. Read-Only: This server has NO capability to create, edit, or delete data. It is inherently safe.
  2. Local Only: Credentials NEVER leave your machine.
  3. Auditability: All API requests are standard HTTPS and appear in your Freshservice API logs.

πŸ“„ License

ISC License. Build with freedom.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured