MCP Server
Give AI assistants native access to your help desk using the Model Context Protocol.
Go Help Desk includes a built-in Model Context Protocol (MCP) server mounted at /mcp/. MCP allows AI assistants — Claude, Cursor, VS Code with Continue, and others — to call help desk operations as structured tools, rather than trying to interact with the web UI.
With the MCP server connected, an AI assistant can:
- List open tickets and summarize them
- Look up the details and history of a specific ticket
- Create a ticket on behalf of a user
- Add a reply or internal note
- Change a ticket's status or assignee
The MCP server sits on top of the REST API — every operation goes through the same permission checks. An AI assistant using a Staff user's API key cannot do anything a Staff user couldn't do manually.
Available tools
Five tools, all requiring a Staff or Admin account. Identifiers are UUIDs.
get_ticket
Get a ticket by its UUID or tracking number.
| Parameter | Type | Description |
|---|---|---|
id | string (required) | Ticket UUID, or tracking number such as OHD-2026-000001. |
list_tickets
List tickets assigned to a user.
| Parameter | Type | Description |
|---|---|---|
assignee_user_id | string (required) | Assignee user UUID. |
limit | number (optional) | Maximum results. Default 20. |
offset | number (optional) | Pagination offset. |
This lists by assignee only. It does not filter by status, priority, category or free text — use the REST API for those.
create_ticket
Open a new ticket.
| Parameter | Type | Description |
|---|---|---|
subject | string (required) | Short summary. |
category_id | string (required) | Category UUID. |
description | string (optional) | Full description. |
priority | string (optional) | critical, high, medium or low. Default medium. |
reporter_user_id | string (optional) | Who the ticket is for. Defaults to the authenticated caller. |
add_reply
Add a reply to a ticket, authored by the authenticated caller.
| Parameter | Type | Description |
|---|---|---|
ticket_id | string (required) | Ticket UUID. |
body | string (required) | Reply body. |
Replies posted through MCP are public and notify the reporter. There is no internal-note option here; use the REST API or the web UI for internal notes.
assign_ticket
Assign a ticket to a user or a group, performed as the authenticated caller.
| Parameter | Type | Description |
|---|---|---|
ticket_id | string (required) | Ticket UUID. |
assignee_user_id | string (optional) | User UUID to assign to. |
assignee_group_id | string (optional) | Group UUID to assign to. |
Omitting both clears the assignment.
Connecting clients
Claude (claude.ai / Claude Code)
Add a server entry to your MCP configuration. In Claude Code, this lives in .claude/mcp.json (project-level) or ~/.claude/mcp.json (global).
{
"mcpServers": {
"helpdesk": {
"type": "http",
"url": "https://helpdesk.example.com/mcp/",
"headers": {
"Authorization": "ApiKey 3f8a…"
}
}
}
}
After saving, Claude will have access to the help desk tools in any conversation where MCP is active.
VS Code with Continue
// .continue/config.json
{
"experimental": {
"modelContextProtocolServers": [
{
"transport": {
"type": "http",
"url": "https://helpdesk.example.com/mcp/",
"requestOptions": {
"headers": {
"Authorization": "ApiKey 3f8a…"
}
}
}
}
]
}
}
Cursor
// cursor/mcp.json (in project root or ~/.cursor/mcp.json)
{
"mcpServers": {
"helpdesk": {
"url": "https://helpdesk.example.com/mcp/",
"headers": {
"Authorization": "ApiKey 3f8a…"
}
}
}
}
Any HTTP MCP client
The MCP server implements the standard Streamable HTTP transport. Point any compliant client at:
https://<BASE_URL>/mcp/
Include an Authorization header with either an API key or a JWT from the OAuth2 token endpoint.
Authentication
Run v1.2.0 before exposing /mcp/. Two separate problems, both fixed:
- In v1.0.0, v1.0.1 and v1.1.0 the MCP server required no authentication at all — anyone who could reach the port could read and write any ticket. Fixed in v1.1.1: GHSA-2x4f-j4jv-m2cm.
- Up to and including v1.1.1, the tools were authenticated but not scope-checked, so a credential reached every tool whatever scopes it held. Fixed in v1.2.0: GHSA-p2wx-wvfr-7h3p. See Upgrading to 1.2.0.
Since v1.1.1 the MCP server sits behind the same authentication middleware as the REST API, and accepts any of:
- API key (recommended for long-lived client configs) —
Authorization: ApiKey <token>— 64 hex characters, no prefix, shown once when the key is created - OAuth2 JWT (recommended for server-to-server) — obtain a token from
POST /api/v1/auth/oauth/tokenand send it asAuthorization: Bearer <jwt>. - Session cookie — works, but is only useful from a browser context.
Unauthenticated requests receive 401. Requests from an account without the required role receive 403.
One API key per integration — create a dedicated API key for each AI assistant or integration that connects to the MCP server. This lets you revoke a single client's access without affecting others, and gives you a named audit trail in logs.
Permissions
The MCP server is restricted to Staff and Admin accounts. A reporting user receives 403 and cannot reach any tool, regardless of which ticket they are asking about.
That is deliberately stricter than the REST API, which lets a reporting user read their own tickets by applying a scope check in each handler. Duplicating those checks in a second surface is how the two drifted apart in the first place, so the MCP surface takes the narrower rule instead.
| Tool | Required role | Notes |
|---|---|---|
get_ticket | Staff / Admin | Any ticket, by UUID or tracking number. |
list_tickets | Staff / Admin | Lists by assignee. |
create_ticket | Staff / Admin | Reporter defaults to the authenticated caller. |
add_reply | Staff / Admin | Authored by the authenticated caller. |
assign_ticket | Staff / Admin | Performed as the authenticated caller. |
Group scoping applies from v1.2.0. Every tool that names a ticket checks that the caller may see it, using the same rule as the REST API: a Staff account reaches tickets assigned to it or its groups, and a reporting user reaches only its own. A ticket the caller may not see is reported as not found rather than refused, so the tools cannot be used to probe which tracking numbers exist.
Up to and including v1.1.1 there was no such check: a Staff account reached any ticket through these tools. If you are on an earlier version, do not grant MCP access to accounts that should not see every ticket.
Identity comes from the request, never from a tool argument. Before v1.1.1, add_reply and assign_ticket accepted author_user_id and actor_user_id parameters — a caller named itself and the server believed it. Those parameters no longer exist. The one identity field that remains, reporter_user_id on create_ticket, names the subject of a ticket rather than the caller, because staff legitimately open tickets on someone's behalf.
MFA is enforced for parity with the ticket API, so MCP cannot be used to sidestep a TOTP challenge. API keys and bearer tokens are unaffected.
If a tool call fails a permission check, the MCP server returns a structured error and does not execute the operation. The assistant receives a description of the error and can inform the user.