freshdesk-mcp
A self-hosted Model Context Protocol (MCP) server that exposes Freshdesk support data to MCP-compatible AI clients (Claude, Cursor, VS Code Copilot, etc.).
What it does
Connects your AI assistant directly to Freshdesk β search tickets, read conversations, extract text from attachments (including OCR for screenshots), and enrich results with status names, group names, and company IDs.
AI client β HTTPS POST /mcp β freshdesk-mcp β Freshdesk API
β GCP Vision OCR (image attachments)
Available Tools
| Tool | Description |
|---|
get_ticket | Fetch a single ticket by ID. Returns status name, group name, company ID. |
get_ticket_summary | Ticket + all conversations + attachments in one call. |
batch_get_ticket_summaries | Multiple ticket summaries in parallel. |
search_tickets | Filter by query, status, priority, type, overdue, escalated, dates, company, requester, agent, group. Full ticket history. |
list_tickets | All tickets with optional filters. |
get_conversations | All replies and notes for a ticket (fully paginated). |
list_attachments | All attachments across ticket and conversations. Filters scanning placeholders. |
get_attachment_text | Extract text from docx, xlsx, json, txt, csv, png, jpg (Vision OCR). |
query_attachment | Search within a JSON attachment. |
find_image_attachments | Scan multiple tickets for image attachments. |
get_description_images | OCR inline images in ticket description HTML and conversation replies. |
find_requester | Search contacts by name/email β requester_id. |
find_company | Search companies by name β company_id. |
find_agent | Search agents by name/email β agent_id. β οΈ Requires admin API key. |
list_groups | List all agent groups β group_id. β οΈ Requires admin API key. |
Note: find_agent and list_groups use Freshdesk admin-only endpoints (/api/v2/agents, /api/v2/groups). They work if your API key belongs to an admin account. Regular agent API keys will receive a 403.
Prerequisites
- A Freshdesk account with API access
- Docker
- A GCP project with the Vision API enabled (optional β needed for image OCR only)
- A container runtime β Cloud Run, AWS App Runner, Azure Container Apps, or plain Docker
Configuration
| Variable | Required | Description |
|---|
FRESHDESK_DOMAIN | yes | Freshdesk subdomain only β e.g. mycompany (not mycompany.freshdesk.com) |
FRESHDESK_API_KEY | yes | Freshdesk API key. Find it at Profile β Profile Settings β API Key. |
MCP_TOKEN | yes (HTTP mode) | Bearer token your MCP client sends in Authorization: Bearer <token>. Generate any random secret. |
GCP_VISION_PROJECT | no | GCP project ID for Vision OCR. If unset, image OCR tools return an error. |
MCP_TRANSPORT | no | Set to http for HTTP transport (default in the Docker image). |
PORT | no | HTTP port (default 8080). Set automatically by Cloud Run. |
Deployment
Docker (any platform)
# Pull pre-built image
docker pull ghcr.io/omnom62/freshdesk-mcp:latest
# Or build from source
docker build -t freshdesk-mcp .
docker run -p 8080:8080 \
-e MCP_TRANSPORT=http \
-e FRESHDESK_DOMAIN=mycompany \
-e FRESHDESK_API_KEY=your-api-key \
-e MCP_TOKEN=your-random-secret \
-e GCP_VISION_PROJECT=my-gcp-project \
freshdesk-mcp
GCP Cloud Run
Build and push to Artifact Registry, then deploy:
IMAGE="<region>-docker.pkg.dev/<project>/freshdesk-mcp/freshdesk-mcp"
docker build -t ${IMAGE}:latest .
DIGEST=$(docker push ${IMAGE}:latest | grep "digest:" | awk '{print $3}')
gcloud run deploy freshdesk-mcp \
--image ${IMAGE}@${DIGEST} \
--region <region> \
--platform managed \
--allow-unauthenticated \
--set-secrets FRESHDESK_DOMAIN=FRESHDESK_DOMAIN:latest,FRESHDESK_API_KEY=FRESHDESK_API_KEY:latest,MCP_TOKEN=MCP_TOKEN:latest \
--set-env-vars GCP_VISION_PROJECT=<project> \
--project <project>
Store secrets in GCP Secret Manager and grant the Cloud Run runtime service account roles/secretmanager.secretAccessor on each secret.
AWS App Runner / Azure Container Apps
Deploy the Docker image to your preferred platform. Pass the configuration variables as environment variables or secrets via your platform's secret store.
Connecting your MCP client
Once deployed, add to your MCP client config:
{
"mcpServers": {
"freshdesk": {
"type": "http",
"url": "https://your-deployment-url/mcp",
"headers": {
"Authorization": "Bearer your-mcp-token"
}
}
}
}
Secret rotation
When rotating the Freshdesk API key:
- Get the new key from Freshdesk β Profile β Profile Settings β API Key
- Verify it works:
curl -s -u "<new-key>:X" "https://<domain>.freshdesk.com/api/v2/tickets?per_page=1"
- Update your secret store (e.g. GCP Secret Manager:
echo -n "<new-key>" | gcloud secrets versions add FRESHDESK_API_KEY --data-file=- --project <project>)
- Redeploy to pick up the new version
Tip: Never include :X in the stored secret value β that suffix is only used in curl Basic auth syntax.
Local development
export FRESHDESK_DOMAIN=mycompany
export FRESHDESK_API_KEY=your-api-key
export MCP_TOKEN=dev-token
export GCP_VISION_PROJECT=my-gcp-project # optional
go run .
Server starts on port 8080. MCP endpoint: POST /mcp.
License
MIT