Skip to main content
Glama
cbreland-DLR

FS_MCP_thin

by cbreland-DLR

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.


Related MCP server: Freshservice MCP Server

πŸ›  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.

F
license - not found
-
quality - not tested
B
maintenance

Maintenance

–Maintainers
–Response time
–Release cycle
–Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

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

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/cbreland-DLR/FS_MCP_thin'

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