Metadata-Version: 2.5
Name: freshdesk-mcp-iplweb
Version: 1.3.0
Summary: MCP server for Freshdesk (iplweb fork) - MCP Python SDK 2.x, extra CRUD, filtering and bulk-fetch tools
Project-URL: Homepage, https://github.com/mpasternak/freshdesk_mcp
Project-URL: Repository, https://github.com/mpasternak/freshdesk_mcp
Project-URL: Issues, https://github.com/mpasternak/freshdesk_mcp/issues
Project-URL: Upstream project, https://github.com/effytech/freshdesk_mcp
Author-email: Gopi Krishnan <gopi@effy.co.in>, Maanaesh Swamy <maanaesh.s@effy.co.in>
Maintainer-email: Michał Pasternak <michal.dtz@gmail.com>
License-Expression: MIT
License-File: LICENSE
Keywords: freshdesk,helpdesk,llm,mcp,model-context-protocol,ticketing
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Customer Service
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Communications :: Email
Classifier: Topic :: Office/Business
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Requires-Dist: httpx==0.28.1
Requires-Dist: mcp==2.0.0
Requires-Dist: pydantic<3,>=2.12
Description-Content-Type: text/markdown

# Freshdesk MCP Server (iplweb fork)

[![PyPI](https://img.shields.io/pypi/v/freshdesk-mcp-iplweb.svg)](https://pypi.org/project/freshdesk-mcp-iplweb/)
[![Python versions](https://img.shields.io/pypi/pyversions/freshdesk-mcp-iplweb.svg)](https://pypi.org/project/freshdesk-mcp-iplweb/)
[![CI](https://github.com/mpasternak/freshdesk_mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/mpasternak/freshdesk_mcp/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)

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](https://github.com/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](#what-this-fork-adds). Upstream remains the original
> project; all credit for the server itself goes there.

## Features

- **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

## Components

### Tools

The server offers several tools for Freshdesk operations:

- `create_ticket`: Create new support tickets
  - **Inputs**:
    - `subject` (string, required): Ticket subject
    - `description` (string, required): Ticket description
    - `source` (number, required): Ticket source code
    - `priority` (number, required): Ticket priority level
    - `status` (number, required): Ticket status code
    - `email` (string, optional): Email of the requester
    - `requester_id` (number, optional): ID of the requester
    - `custom_fields` (object, optional): Custom fields to set on the ticket
    - `additional_fields` (object, optional): Additional top-level fields

- `update_ticket`: Update existing tickets
  - **Inputs**:
    - `ticket_id` (number, required): ID of the ticket to update
    - `ticket_fields` (object, required): Fields to update

- `delete_ticket`: Delete a ticket
  - **Inputs**:
    - `ticket_id` (number, required): ID of the ticket to delete

- `search_tickets`: Search for tickets based on criteria
  - **Inputs**:
    - `query` (string, required): Search query string

- `get_ticket_fields`: Get all ticket fields
  - **Inputs**:
    - None

- `get_tickets`: Get all tickets
  - **Inputs**:
    - `page` (number, optional): Page number to fetch
    - `per_page` (number, optional): Number of tickets per page

- `get_ticket`: Get a single ticket
  - **Inputs**:
    - `ticket_id` (number, required): ID of the ticket to get

- `get_ticket_conversation`: Get conversation for a ticket
  - **Inputs**:
    - `ticket_id` (number, required): ID of the ticket

- `create_ticket_reply`: Reply to a ticket
  - **Inputs**:
    - `ticket_id` (number, required): ID of the ticket
    - `body` (string, required): Content of the reply
    - `cc_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 recipient
    - `bcc_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 recipient
    - `from_email` (string, optional): Email address the reply is sent from
    - `user_id` (number, optional): ID of the agent who is adding the reply

- `create_ticket_note`: Add a note to a ticket
  - **Inputs**:
    - `ticket_id` (number, required): ID of the ticket
    - `body` (string, required): Content of the note

- `update_ticket_conversation`: Update a conversation
  - **Inputs**:
    - `conversation_id` (number, required): ID of the conversation
    - `body` (string, required): Updated content

- `view_ticket_summary`: Get the summary of a ticket
  - **Inputs**:
    - `ticket_id` (number, required): ID of the ticket

- `update_ticket_summary`: Update the summary of a ticket
  - **Inputs**:
    - `ticket_id` (number, required): ID of the ticket
    - `body` (string, required): New summary content

- `delete_ticket_summary`: Delete the summary of a ticket
  - **Inputs**:
    - `ticket_id` (number, required): ID of the ticket

- `get_agents`: Get all agents
  - **Inputs**:
    - `page` (number, optional): Page number
    - `per_page` (number, optional): Number of agents per page

- `view_agent`: Get a single agent
  - **Inputs**:
    - `agent_id` (number, required): ID of the agent

- `create_agent`: Create a new agent
  - **Inputs**:
    - `agent_fields` (object, required): Agent details

- `update_agent`: Update an agent
  - **Inputs**:
    - `agent_id` (number, required): ID of the agent
    - `agent_fields` (object, required): Fields to update

- `search_agents`: Search for agents
  - **Inputs**:
    - `query` (string, required): Search query

- `list_contacts`: Get all contacts
  - **Inputs**:
    - `page` (number, optional): Page number
    - `per_page` (number, optional): Contacts per page

- `get_contact`: Get a single contact
  - **Inputs**:
    - `contact_id` (number, required): ID of the contact

- `search_contacts`: Search for contacts
  - **Inputs**:
    - `query` (string, required): Search query

- `update_contact`: Update a contact
  - **Inputs**:
    - `contact_id` (number, required): ID of the contact
    - `contact_fields` (object, required): Fields to update

- `list_companies`: Get all companies
  - **Inputs**:
    - `page` (number, optional): Page number
    - `per_page` (number, optional): Companies per page

- `view_company`: Get a single company
  - **Inputs**:
    - `company_id` (number, required): ID of the company

- `search_companies`: Search for companies
  - **Inputs**:
    - `query` (string, required): Search query

- `find_company_by_name`: Find a company by name
  - **Inputs**:
    - `name` (string, required): Company name

- `list_company_fields`: Get all company fields
  - **Inputs**:
    - None

#### Bulk fetch / archaeology

- `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 ticket
    - `include_requester` (bool, optional, default `true`)
    - `include_agent` (bool, optional, default `true`)
    - `decode_status` (bool, optional, default `true`) — adds `status_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 `jq` rather than re-reading whole.

- `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_DIR` or `/tmp/fd`
    - `size_limit_mb` (number, optional, default `50`): per-file cap; larger files reported as errors

- `extract_inline_images`: Resolve `cid:` 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, default `25`)

- `decode_ticket_status`: Resolve a status integer to its label (handles custom statuses)
  - **Inputs**:
    - `status_id` (number, required)

## Getting Started

### Installing via Smithery

To install freshdesk_mcp for Claude Desktop automatically via [Smithery](https://smithery.ai/server/@effytech/freshdesk_mcp):

```bash
npx -y @smithery/cli install @effytech/freshdesk_mcp --client claude
```

### Prerequisites

- A Freshdesk account (sign up at [freshdesk.com](https://freshdesk.com))
- Freshdesk API key
- `uvx` installed (`pip install uv` or `brew install uv`)

### What this fork adds

This fork tracks the stable MCP Python SDK 2.x line and additionally carries
three pull requests still open against upstream:

- [#45](https://github.com/effytech/freshdesk_mcp/pull/45) — missing CRUD tools
  (contacts, companies, and the `delete_*` counterparts of existing tools).
- [#46](https://github.com/effytech/freshdesk_mcp/pull/46) — filtering, sorting
  and pagination on `get_tickets` / `search_tickets` /
  `get_ticket_conversation`. Note that `get_ticket_conversation` now returns
  `{"conversations": [...], "pagination": {...}}` instead of a bare list.
- [#47](https://github.com/effytech/freshdesk_mcp/pull/47) — bulk fetch tools:
  `get_ticket_full`, `download_ticket_attachments`, `extract_inline_images`,
  `decode_ticket_status`, hardened in this fork (see below).

### Hardening applied to the bulk fetch tools

Ticket bodies are written by whoever emails the helpdesk, so this fork treats
anything derived from them as untrusted input:

- `extract_inline_images` refuses `<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 carries `conversations_truncated` so a caller can tell.
- Downloads run at most `FRESHDESK_DOWNLOAD_CONCURRENCY` at a time (default 5),
  capped at `FRESHDESK_MAX_DOWNLOAD_FILES` files (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 mode `0700`, instead of a shared `/tmp/fd`. Override
  with `FRESHDESK_DOWNLOAD_DIR`.

That makes 78 tools instead of upstream's 59.

### Installation

From PyPI:

```bash
uvx freshdesk-mcp-iplweb
```

The 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:

```bash
uvx --isolated --from git+https://github.com/mpasternak/freshdesk_mcp.git@main freshdesk-mcp-iplweb
```

### Configuration

1. Generate your Freshdesk API key from the Freshdesk admin panel
2. Set up your domain and authentication details

### Usage with Claude Desktop

1. Install Claude Desktop if you haven't already
2. Add the following configuration to your `claude_desktop_config.json`:

```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_KEY` with your actual Freshdesk API key
- Replace `YOUR_FRESHDESK_DOMAIN` with your Freshdesk domain (e.g., `yourcompany.freshdesk.com`)

## Example Operations

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"


## Testing

For testing purposes, you can start the server manually:

```bash
FRESHDESK_API_KEY=<your_api_key> \
FRESHDESK_DOMAIN=<your_domain> \
uvx freshdesk-mcp-iplweb
```

## Troubleshooting

- Verify your Freshdesk API key and domain are correct
- Ensure proper network connectivity to Freshdesk servers
- Check API rate limits and quotas
- Verify the `uvx` command is available in your PATH

## License

This MCP server is licensed under the MIT License. See the LICENSE file in the project repository for full details.
