An MCP server implementation that integrates with Freshdesk, enabling AI models to interact with Freshdesk modules and perform various support operations.
This is a fork of effytech/freshdesk_mcp, published to PyPI as
freshdesk-mcp-iplweb. It runs on the MCP Python SDK 2.x and carries three pull requests still open upstream — 78 tools instead of 59. See What this fork adds. Upstream remains the original project; all credit for the server itself goes there.
- Freshdesk Integration: Seamless interaction with Freshdesk API endpoints
- AI Model Support: Enables AI models to perform support operations through Freshdesk
- Automated Ticket Management: Handle ticket creation, updates, and responses
The server offers several tools for Freshdesk operations:
-
create_ticket: Create new support tickets- Inputs:
subject(string, required): Ticket subjectdescription(string, required): Ticket descriptionsource(number, required): Ticket source codepriority(number, required): Ticket priority levelstatus(number, required): Ticket status codeemail(string, optional): Email of the requesterrequester_id(number, optional): ID of the requestercustom_fields(object, optional): Custom fields to set on the ticketadditional_fields(object, optional): Additional top-level fields
- Inputs:
-
update_ticket: Update existing tickets- Inputs:
ticket_id(number, required): ID of the ticket to updateticket_fields(object, required): Fields to update
- Inputs:
-
delete_ticket: Delete a ticket- Inputs:
ticket_id(number, required): ID of the ticket to delete
- Inputs:
-
search_tickets: Search for tickets based on criteria- Inputs:
query(string, required): Search query string
- Inputs:
-
get_ticket_fields: Get all ticket fields- Inputs:
- None
- Inputs:
-
get_tickets: Get all tickets- Inputs:
page(number, optional): Page number to fetchper_page(number, optional): Number of tickets per page
- Inputs:
-
get_ticket: Get a single ticket- Inputs:
ticket_id(number, required): ID of the ticket to get
- Inputs:
-
get_ticket_conversation: Get conversation for a ticket- Inputs:
ticket_id(number, required): ID of the ticket
- Inputs:
-
create_ticket_reply: Reply to a ticket- Inputs:
ticket_id(number, required): ID of the ticketbody(string, required): Content of the replycc_emails(array of strings, optional): Additional email addresses added to the 'cc' field of the outgoing email. These supplement the ticket requester, who always remains the primary recipientbcc_emails(array of strings, optional): Additional email addresses added to the 'bcc' field of the outgoing email. These supplement the ticket requester, who always remains the primary recipientfrom_email(string, optional): Email address the reply is sent fromuser_id(number, optional): ID of the agent who is adding the reply
- Inputs:
-
create_ticket_note: Add a note to a ticket- Inputs:
ticket_id(number, required): ID of the ticketbody(string, required): Content of the note
- Inputs:
-
update_ticket_conversation: Update a conversation- Inputs:
conversation_id(number, required): ID of the conversationbody(string, required): Updated content
- Inputs:
-
view_ticket_summary: Get the summary of a ticket- Inputs:
ticket_id(number, required): ID of the ticket
- Inputs:
-
update_ticket_summary: Update the summary of a ticket- Inputs:
ticket_id(number, required): ID of the ticketbody(string, required): New summary content
- Inputs:
-
delete_ticket_summary: Delete the summary of a ticket- Inputs:
ticket_id(number, required): ID of the ticket
- Inputs:
-
get_agents: Get all agents- Inputs:
page(number, optional): Page numberper_page(number, optional): Number of agents per page
- Inputs:
-
view_agent: Get a single agent- Inputs:
agent_id(number, required): ID of the agent
- Inputs:
-
create_agent: Create a new agent- Inputs:
agent_fields(object, required): Agent details
- Inputs:
-
update_agent: Update an agent- Inputs:
agent_id(number, required): ID of the agentagent_fields(object, required): Fields to update
- Inputs:
-
search_agents: Search for agents- Inputs:
query(string, required): Search query
- Inputs:
-
list_contacts: Get all contacts- Inputs:
page(number, optional): Page numberper_page(number, optional): Contacts per page
- Inputs:
-
get_contact: Get a single contact- Inputs:
contact_id(number, required): ID of the contact
- Inputs:
-
search_contacts: Search for contacts- Inputs:
query(string, required): Search query
- Inputs:
-
update_contact: Update a contact- Inputs:
contact_id(number, required): ID of the contactcontact_fields(object, required): Fields to update
- Inputs:
-
list_companies: Get all companies- Inputs:
page(number, optional): Page numberper_page(number, optional): Companies per page
- Inputs:
-
view_company: Get a single company- Inputs:
company_id(number, required): ID of the company
- Inputs:
-
search_companies: Search for companies- Inputs:
query(string, required): Search query
- Inputs:
-
find_company_by_name: Find a company by name- Inputs:
name(string, required): Company name
- Inputs:
-
list_company_fields: Get all company fields- Inputs:
- None
- Inputs:
-
get_ticket_full: Fetch ticket + ALL conversations (paginated, no truncation), with optional requester/agent expansion and status label decoding- Inputs:
ticket_id(number, required): ID of the ticketinclude_requester(bool, optional, defaulttrue)include_agent(bool, optional, defaulttrue)decode_status(bool, optional, defaulttrue) — addsstatus_label
- Returns: ticket fields,
conversations[],requester,agent,status_label,attachments_index - Note: Output for busy tickets routinely exceeds 256 KB / 25 k tokens. MCP hosts will spill the result to disk; slice with
jqrather than re-reading whole.
- Inputs:
-
download_ticket_attachments: Download all attachments (ticket-level + per-conversation) to disk- Inputs:
ticket_id(number, required)dest_dir(string, optional): defaults to$FRESHDESK_DOWNLOAD_DIRor/tmp/fdsize_limit_mb(number, optional, default50): per-file cap; larger files reported as errors
- Inputs:
-
extract_inline_images: Resolvecid:references against attachments and download remote<img src>URLs from description + every conversation body- Inputs:
ticket_id(number, required)dest_dir(string, optional)size_limit_mb(number, optional, default25)
- Inputs:
-
decode_ticket_status: Resolve a status integer to its label (handles custom statuses)- Inputs:
status_id(number, required)
- Inputs:
To install freshdesk_mcp for Claude Desktop automatically via Smithery:
npx -y @smithery/cli install @effytech/freshdesk_mcp --client claude- A Freshdesk account (sign up at freshdesk.com)
- Freshdesk API key
uvxinstalled (pip install uvorbrew install uv)
This fork tracks the stable MCP Python SDK 2.x line and additionally carries three pull requests still open against upstream:
- #45 — missing CRUD tools
(contacts, companies, and the
delete_*counterparts of existing tools). - #46 — filtering, sorting
and pagination on
get_tickets/search_tickets/get_ticket_conversation. Note thatget_ticket_conversationnow returns{"conversations": [...], "pagination": {...}}instead of a bare list. - #47 — bulk fetch tools:
get_ticket_full,download_ticket_attachments,extract_inline_images,decode_ticket_status, hardened in this fork (see below).
Ticket bodies are written by whoever emails the helpdesk, so this fork treats anything derived from them as untrusted input:
extract_inline_imagesrefuses<img src>URLs that resolve to loopback, link-local, private or otherwise non-public addresses — including across redirects, which are followed one hop at a time and re-checked. Without this, a customer could mail an<img src="http://169.254.169.254/…">and have the server fetch it. Attachment URLs issued by Freshdesk itself are unaffected.- Conversation paging stops at
FRESHDESK_MAX_CONVERSATION_PAGES(default 50) and the result carriesconversations_truncatedso a caller can tell. - Downloads run at most
FRESHDESK_DOWNLOAD_CONCURRENCYat a time (default 5), capped atFRESHDESK_MAX_DOWNLOAD_FILESfiles (default 200), each still bounded by the per-file size limit. - Downloads default to a per-user directory (
freshdesk-mcp-<uid>under the system temp dir) created mode0700, instead of a shared/tmp/fd. Override withFRESHDESK_DOWNLOAD_DIR.
That makes 78 tools instead of upstream's 59.
From PyPI:
uvx freshdesk-mcp-iplwebThe distribution installs two identical console scripts, freshdesk-mcp-iplweb
and freshdesk-mcp, so an existing configuration that calls freshdesk-mcp
keeps working (use uvx --from freshdesk-mcp-iplweb freshdesk-mcp for that
name). Pin a release with freshdesk-mcp-iplweb==1.3.0.
To run an unreleased revision straight from git instead:
uvx --isolated --from git+https://github.com/mpasternak/freshdesk_mcp.git@main freshdesk-mcp-iplweb- Generate your Freshdesk API key from the Freshdesk admin panel
- Set up your domain and authentication details
- Install Claude Desktop if you haven't already
- Add the following configuration to your
claude_desktop_config.json:
"mcpServers": {
"freshdesk-mcp": {
"command": "uvx",
"args": [
"freshdesk-mcp-iplweb"
],
"env": {
"FRESHDESK_API_KEY": "<YOUR_FRESHDESK_API_KEY>",
"FRESHDESK_DOMAIN": "<YOUR_FRESHDESK_DOMAIN>"
}
}
}Important Notes:
- Replace
YOUR_FRESHDESK_API_KEYwith your actual Freshdesk API key - Replace
YOUR_FRESHDESK_DOMAINwith your Freshdesk domain (e.g.,yourcompany.freshdesk.com)
Once configured, you can ask Claude to perform operations like:
- "Create a new ticket with subject 'Payment Issue for customer A101' and description as 'Reaching out for a payment issue in the last month for customer A101', where customer email is a101@acme.com and set priority to high"
- "Update the status of ticket #12345 to 'Resolved'"
- "List all high-priority tickets assigned to the agent John Doe"
- "List previous tickets of customer A101 in last 30 days"
For testing purposes, you can start the server manually:
FRESHDESK_API_KEY=<your_api_key> \
FRESHDESK_DOMAIN=<your_domain> \
uvx freshdesk-mcp-iplweb- Verify your Freshdesk API key and domain are correct
- Ensure proper network connectivity to Freshdesk servers
- Check API rate limits and quotas
- Verify the
uvxcommand is available in your PATH
This MCP server is licensed under the MIT License. See the LICENSE file in the project repository for full details.