> For the complete documentation index, see [llms.txt](https://docs.usepylon.com/pylon-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.usepylon.com/pylon-docs/integrations/pylon-mcp.md).

# Pylon MCP

Expose Pylon data to AI tools and assistants via Model Context Protocol.

## Pylon MCP Server

The Pylon MCP Server exposes Pylon data to AI tools that support the Model Context Protocol (e.g. Claude, ChatGPT, Cursor). AI tools authenticate with your Pylon account via OAuth and can read and update issues, accounts, contacts, knowledge base articles, tasks and projects, triggers, and more within the data you can see in Pylon.

* **Server URL (US):** `https://mcp.usepylon.com`
* **Server URL (EU):** `https://mcp.eu.usepylon.com`
* **Auth:** OAuth 2.0 (AuthKit). Actions are performed on behalf of the authenticated user; access is scoped to the same data as in the Pylon dashboard.
* **Transport:** Streamable HTTP (stateless; no server-side sessions).

### Setup in Pylon

Open **Settings > AI Controls > MCP Server** in Pylon. Copy your workspace's regional MCP URL from **Installation** and use it in your AI tool. For client-specific instructions, see [connecting to the Pylon MCP Server](https://support.usepylon.com/articles/2407390554-connecting-to-the-pylon-mcp-server?lang=en).

### What you can do with MCP today

Member and Admin users need the `MCP Access` [role](https://docs.usepylon.com/pylon-docs/platform/roles-and-user-management#member-permissions-2) enabled to connect. Each tool also requires the permissions for its operation. Access follows the same scoping as the Pylon dashboard — the MCP cannot return data that the authenticated user cannot already see, or perform writes that the authenticated user cannot already write in the UI.

Some tools also require a plan feature, noted in their section. Rate limits apply per tool, elaborated below.

#### **Issues**

AI tools can send replies to customers and post internal notes for your team. A reply goes straight to the customer on the issue's channel (Slack, email, chat, etc.) and can't be unsent, so AI tools are instructed to show you the exact message and get your approval before sending it. Most AI tools also ask you to confirm each reply.

| **Tool**                     | **Read / Write** | **Description**                                                                                                                                                                          |
| ---------------------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`search_issues`**          | Read             | Search issues by keyword (titles, messages, tags, and names) and by state, account, assignee, tags, custom fields, etc. Each result lists its linked engineering tickets and their state |
| **`get_issue`**              | Read             | Fetch a single issue by ID or number; set `include_messages=true` to include its conversation                                                                                            |
| **`get_issue_messages`**     | Read             | Fetch an issue's full message history in order, including the original To and Cc recipients of email messages                                                                            |
| **`get_issue_statuses`**     | Read             | List the default and custom issue statuses configured for your organization                                                                                                              |
| **`create_issue`**           | Write            | Create an issue in your workspace with an initial internal note                                                                                                                          |
| **`update_issue`**           | Write            | Update issue fields (status, assignee, team, priority, tags, custom fields, …); tags can be replaced or added and removed individually                                                   |
| **`update_issues`**          | Write            | Apply the same status, assignee, team, or tag change to up to 100 issues in one call                                                                                                     |
| **`snooze_issue`**           | Write            | Snooze an issue until a future time. It moves to On hold and returns to Waiting on you when the snooze ends                                                                              |
| **`send_issue_reply`**       | Write            | Send a reply to the customer on an issue. For email issues, recipients follow reply-all                                                                                                  |
| **`send_issue_note`**        | Write            | Post an internal note on an issue, visible only to your team                                                                                                                             |
| **`get_issue_threads`**      | Read             | List an issue's internal threads                                                                                                                                                         |
| **`create_issue_thread`**    | Write            | Create an internal thread on an issue, optionally synced to an internal Slack channel                                                                                                    |
| **`get_issue_followers`**    | Read             | List an issue's followers                                                                                                                                                                |
| **`update_issue_followers`** | Write            | Add or remove teammates as followers of an issue                                                                                                                                         |
| **`link_product_issue`**     | Write            | Link a Linear, Jira, GitHub, Asana, or Shortcut ticket to an issue                                                                                                                       |

`search_issues` can return each issue's messages with `include_messages`. On large pages, `max_messages_per_issue` keeps only each issue's latest messages (`messages_truncated` is set when older ones were dropped), and `max_message_chars` cuts each message body to that many characters (`body_truncated` is set). Set `include_total` to also get the exact number of matching issues you can read across all pages; it costs an extra query, so use it when sizing work rather than on every page.

`update_issues` changes only the fields you provide. Issues that don't exist or that you can't update are listed in `skipped_issues` instead of failing the call. Tags replace the issue's tags by default; set `tags_apply_mode` to `append_only` to add tags or `remove_only` to remove them. Use `update_issue` for per-issue changes such as priority or custom fields.

#### **Accounts**

| **Tool**                   | **Read / Write** | **Description**                                                         |
| -------------------------- | ---------------- | ----------------------------------------------------------------------- |
| **`search_accounts`**      | Read             | Search accounts by name, domain, external ID, tags, custom fields, etc. |
| **`get_account`**          | Read             | Fetch a single account, including custom field values                   |
| **`create_account`**       | Write            | Create a new account                                                    |
| **`update_account`**       | Write            | Update account fields                                                   |
| **`upload_account_files`** | Write            | Upload files (e.g. PDFs) to an account's Files tab                      |
| **`create_attachment`**    | Write            | Upload a file and get back an attachment ID and URL                     |

#### **Account Notes**

Requires Account Intelligence and permission to read or update the account.

| **Tool**                | **Read / Write** | **Description**                                                  |
| ----------------------- | ---------------- | ---------------------------------------------------------------- |
| **`get_account_notes`** | Read             | List the notes in an account's Notes block, newest first         |
| **`save_account_note`** | Write            | Create a timestamped account note or edit its title or HTML body |

Both tools work on one Notes block in an account notebook. To get its ID, hover over the Notes block in Pylon, open **Notes block actions**, and select **Copy block ID**. Pass it as `widget_id`.

Use `get_account_notes` with `account_id` and `widget_id` to list notes, up to 20 per page. When `has_next_page` is true, pass the returned `cursor` to fetch older notes. Each note includes its `id`.

Use `save_account_note` without `note_id` to create a note; `account_id`, `widget_id`, and nonempty `content_html` are required.

To edit a note, supply a nonempty `note_id` and `title` and/or `content_html`. Use `get_account_notes` to find note IDs. Omit either field to preserve it; send an empty `title` to clear the title. An empty `content_html` is rejected, and HTML is sanitized. `account_id` and `widget_id` apply only when creating. An explicitly empty `note_id` is rejected; omit it to create.

#### **Contacts, Users & Teams**

| **Tool**              | **Read / Write** | **Description**                                                                                                           |
| --------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **`search_contacts`** | Read             | Search contacts by name, email, phone, account, and more                                                                  |
| **`get_contact`**     | Read             | Fetch a contact by ID                                                                                                     |
| **`save_contact`**    | Write            | Create a contact on an account, update an existing contact's name, account, or custom fields, or merge duplicate contacts |
| **`search_users`**    | Read             | Search Pylon team members by name, or look one up by email                                                                |
| **`get_user`**        | Read             | Fetch a Pylon team member by ID                                                                                           |
| **`get_me`**          | Read             | Return the authenticated user and their organization                                                                      |
| **`search_teams`**    | Read             | Look up teams by name, or list all teams                                                                                  |
| **`get_team`**        | Read             | Read a team's details, members, and subteams                                                                              |
| **`save_team`**       | Write            | Create a team, or update its name, icon, members, and subteams                                                            |

For `save_contact`, omit `contact_id` to create a contact; `name` and `account_id` are required, and `email` is optional. New contacts don't get customer portal access or an invite. To update, read the contact with `get_contact`, then supply a nonempty `contact_id` and only the fields to change. `email` is create-only. Contacts with customer portal access cannot be moved to another account through this tool.

To merge duplicate contacts, supply only `contact_id` and `merge_into_contact_id`; merging needs permission to delete contacts. The contact in `contact_id` is merged into the other one and then permanently deleted, and the merge can't be undone. Its issues, emails, and phone numbers move to the surviving contact. Both contacts must be on the same account, unless `contact_id` has no account, in which case it moves to the surviving contact's account. If that contact can log in to the customer portal, merge it in Pylon instead.

Team reads require permission to view team settings; `save_team` requires permission to edit them. Omit `team_id` to create a team with `name` and `icon`, or supply a nonempty `team_id` to update it. Read `get_team` before changing membership. Removing a teammate also deletes schedule blocks they own in that team. Team changes apply in order; if a later change fails, earlier changes remain applied.

#### **CRM User Mappings**

Map users in your connected Salesforce, HubSpot, Attio, or Pipedrive CRM to Pylon teammates so Pylon can resolve CRM users, such as account owners. Reading requires permission to view apps; saving requires permission to edit apps.

| **Tool**                             | **Read / Write** | **Description**                                                 |
| ------------------------------------ | ---------------- | --------------------------------------------------------------- |
| **`list_integration_user_mappings`** | Read             | List CRM users, current mappings, and email-matched suggestions |
| **`save_integration_user_mappings`** | Write            | Map or unmap the specified CRM users                            |

Use `list_integration_user_mappings` first and confirm suggested matches before saving. Pass the connected CRM as `integration`, then provide `map` pairs of `integration_user_id` and `pylon_user_id`, or `unmap_integration_user_ids`. Mapping a user again replaces their mapped teammate; other mappings are preserved. If a save fails after some changes, read the mappings again before retrying.

#### **Knowledge Base**

Reading requires permission to view the knowledge base. Drafting, publishing, changing article settings and tags, and editing collections require the same edit and publish permissions as the Pylon knowledge base editor.

| **Tool**                         | **Read / Write** | **Description**                                                                                                                        |
| -------------------------------- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| **`list_knowledge_bases`**       | Read             | List the knowledge bases you can read                                                                                                  |
| **`list_collections`**           | Read             | List collections in a knowledge base                                                                                                   |
| **`get_collection`**             | Read             | Fetch a collection's details and visibility settings                                                                                   |
| **`list_collection_contents`**   | Read             | List the articles and sub-collections directly inside a collection                                                                     |
| **`save_collection`**            | Write            | Create a collection, or edit an existing collection's title, description, or slug, or move it under another collection                 |
| **`search_articles`**            | Read             | Full-text search across article titles and content                                                                                     |
| **`get_article`**                | Read             | Fetch an article's content, visibility settings, and tags, by ID or by the identifier in its public URL; optionally include its images |
| **`get_related_links`**          | Read             | List the tracked websites and external sites configured for your org                                                                   |
| **`save_draft_article`**         | Write            | Create a draft article, or save new draft content for an existing article without publishing                                           |
| **`publish_article`**            | Write            | Publish an article's content                                                                                                           |
| **`update_article_settings`**    | Write            | Change an article's visibility, AI agent access, and tags                                                                              |
| **`move_article_to_collection`** | Write            | Move an article into a different collection                                                                                            |

`get_article` doesn't download images by default. Set `include_images` to `true` when your AI tool needs to look at an article's images, for example to check screenshots or alt text. Images hosted in Pylon are returned as image content along with each image's URL and alt text; images hosted elsewhere stay as URLs in the article text. Images in both the draft and the published version are included once, draft first. PNG, JPEG, GIF, and WebP are supported, up to 5 images per call, 5 MB each and 10 MB in total. Images that can't be attached are noted in the response.

To tag an article, pass `tag_ids` to `update_article_settings`. The list replaces the article's current tags, so to add or remove one tag, read the current tags with `get_article` and send the full new list. Send an empty list to remove every tag. Use `list_tags` with `object_type` set to `article` to find tag IDs, and `save_tag` to create a new article tag.

For `save_collection`, omit `collection_id` to create a collection. `title` is required, along with exactly one of `knowledge_base_id`, to create the collection at the top level of a knowledge base, or `parent_collection_id`, to nest it under another collection. New collections inherit visibility and AI agent access from where they're created.

To edit a collection, supply its `collection_id` and only the `title`, `description`, or `slug` to change; send an empty `description` to clear it. Pass `parent_collection_id` to move the collection, along with its articles and sub-collections, under another collection in the same knowledge base. Use `list_knowledge_bases` and `list_collections` to find IDs. Change a collection's visibility and AI agent access in Pylon.

#### **Feature Requests**

Requires the Feature Requests plan feature.

| **Tool**                                    | **Read / Write** | **Description**                                                                                                     |
| ------------------------------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------- |
| **`search_feature_requests`**               | Read             | Search feature requests by status and other filters                                                                 |
| **`get_feature_request`**                   | Read             | Fetch a feature request, including its evidence and the accounts that can see it in the customer portal             |
| **`get_feature_request_statuses`**          | Read             | List the feature request statuses configured for your org                                                           |
| **`save_feature_request`**                  | Write            | Create a feature request with optional initial evidence, or update its title, description, status, or custom fields |
| **`add_evidence_to_feature_request`**       | Write            | Record that a customer asked for an existing feature request, linking the issue or account                          |
| **`merge_feature_requests`**                | Write            | Merge duplicate feature requests into one; evidence and linked tickets move over and the duplicates are archived    |
| **`remove_feature_request_evidence`**       | Write            | Unlink evidence that doesn't support a feature request, such as an issue that asked for something different         |
| **`set_feature_request_portal_visibility`** | Write            | Show or hide feature requests in the customer portal for specific accounts                                          |
| **`delete_feature_request`**                | Write            | Permanently delete a feature request                                                                                |

For `save_feature_request`, omit `feature_request_id` to create a request with a nonempty `title` and `description`. Search first; if a matching request exists, use `add_evidence_to_feature_request` instead. `issue_id`, `account_id`, and `evidence_summary` apply only when creating.

Supply a nonempty `feature_request_id` to update only the provided fields. `request_status` and `custom_fields` apply only when updating; use `get_feature_request_statuses` to find valid statuses. Results contain the new request under `created` or the updated request under `updated`.

`remove_feature_request_evidence` takes a `feature_request_id` and up to 50 evidence IDs from `get_feature_request`; every ID must belong to that request. The source issue, call, or survey response isn't deleted. Accounts left without evidence on the request can no longer see it in the customer portal.

`set_feature_request_portal_visibility` applies to every pair of the `feature_request_ids` and `account_ids` you pass, so you can share one request with many accounts or many requests with one account, up to 500 pairs per call. A request can only be shown to accounts that asked for it, meaning they have evidence on it. Changes are all or nothing: if one pair fails, none are applied. The result lists which accounts can see each request afterward.

{% hint style="danger" %}
`delete_feature_request` permanently deletes the request along with its evidence links, linked product issues, and portal visibility, and can't be undone. To combine duplicates, use `merge_feature_requests` so the evidence is kept. To retire a stale or rejected request, archive it by updating its status with `save_feature_request`. AI tools are instructed to confirm with you before deleting.
{% endhint %}

#### **Tasks & Projects**

Requires Account Intelligence.

| **Tool**                    | **Read / Write** | **Description**                                                                            |
| --------------------------- | ---------------- | ------------------------------------------------------------------------------------------ |
| **`search_tasks`**          | Read             | Search tasks across your organization, or for one account or project                       |
| **`get_task`**              | Read             | Fetch a task, including its subtasks and 20 most recent comments                           |
| **`get_task_statuses`**     | Read             | List the default and custom task statuses                                                  |
| **`save_task`**             | Write            | Create a task or update only the fields you provide                                        |
| **`save_task_comment`**     | Write            | Add a task comment, or replace the body of a comment you authored                          |
| **`delete_task`**           | Write            | Delete a task and its subtasks                                                             |
| **`search_projects`**       | Read             | Search or list projects by name, account, owner, and status                                |
| **`get_project`**           | Read             | Fetch a project's details and progress                                                     |
| **`save_project`**          | Write            | Create a project for an account, optionally from a template, or update an existing project |
| **`get_project_templates`** | Read             | List project templates                                                                     |
| **`get_milestones`**        | Read             | List milestones for a project or account, or fetch one by ID                               |
| **`save_milestone`**        | Write            | Create a milestone in a project or update an existing milestone                            |

For `save_task`, `save_project`, and `save_milestone`, omit the object's ID to create it. Supply a nonempty `task_id`, `project_id`, or `milestone_id` to update only the fields you provide; omitted fields keep their current values. An explicitly empty ID is rejected. Read the existing object before updating it.

* **Tasks:** Creating requires `title`. `parent_task_id` applies only when creating. `completed_at` applies only when updating an already completed task and cannot be cleared. On updates, send an empty string for `due_date`, `assignee_id`, or an account, project, or milestone assignment to clear it.
* **Projects:** Creating always requires `account_id`. Also provide `name`, or supply `project_template_id` to copy a template's milestones, tasks, and subtasks. `account_id`, `owner_type`, and `project_template_id` apply only when creating; `is_archived` applies only when updating. On updates, send an empty string for `start_date`, `end_date`, or `owner_id` to clear it.
* **Milestones:** Creating requires `name` and `project_id`. `project_id` and `account_id` apply only when creating. On updates, send an empty `due_date` to clear it.

Tasks and projects accept `custom_fields` when creating or updating. Use `get_custom_fields` with `object_type` set to `task` or `project` to discover field slugs and values first.

For `save_task_comment`, provide `task_id` and a `body_html` containing text. Omit `comment_id` to create, or supply a nonempty `comment_id` to edit your own comment. New comments default to `is_internal=false` and may be visible to customers; set `is_internal=true` when creating an internal comment. This setting cannot be changed when editing.

Use `get_task` to find comment IDs. Returned comment bodies are limited to 2,000 characters and marked `body_truncated=true` when shortened. Don't edit using a truncated body: saving replaces the entire comment body. Open the task in Pylon to review the full comment first.

#### **Call Recordings**

Requires Account Intelligence. Access follows the same per-recording permissions as in Pylon.

| **Tool**                     | **Read / Write** | **Description**                                                                                                 |
| ---------------------------- | ---------------- | --------------------------------------------------------------------------------------------------------------- |
| **`search_call_recordings`** | Read             | Search call recordings by title or account name, or by what was said during the call                            |
| **`get_call_recording`**     | Read             | Fetch a recording's details, participants, summary, and full transcript, or list an account's recent recordings |

#### **Surveys**

| **Tool**                   | **Read / Write** | **Description**                           |
| -------------------------- | ---------------- | ----------------------------------------- |
| **`list_surveys`**         | Read             | List NPS, CSAT, and custom surveys        |
| **`get_survey_responses`** | Read             | Fetch survey responses by survey or issue |

#### **Triggers**

New triggers are created disabled so you can review them in Pylon before turning them on.

Use `validate_trigger` before saving. `save_trigger` supports custom trigger groups and flat branches with compatible actions, delays, and conditions, including recurring schedule kickoffs. Configure default or special groups, phone/IVR triggers, nested branches, and background-agent investigations in Pylon instead. Updating a trigger replaces its editable configuration while preserving its group and enabled state.

To build a recurring schedule, call `describe_trigger_kickoff` with `kickoff_type` `recurring_schedule` and the `object_type` the schedule runs on (for example `issue` or `account`). It returns the schedule fields and the actions that object supports; `get_trigger_examples` includes a weekday schedule example. Every enabled branch of a scheduled trigger needs a filter that selects which records it acts on. `build_filter` can't build meeting filters, so reuse an existing meeting filter from `get_trigger` or set it up in Pylon. To change an existing schedule, start from its `get_trigger` configuration. If a schedule uses recurrence settings that `save_trigger` can't represent, the update is rejected and the trigger is left unchanged; edit it in Pylon instead.

| **Tool**                       | **Read / Write** | **Description**                                                                              |
| ------------------------------ | ---------------- | -------------------------------------------------------------------------------------------- |
| **`list_trigger_groups`**      | Read             | List trigger groups                                                                          |
| **`list_triggers`**            | Read             | List triggers with their kickoffs, actions, and firing statistics                            |
| **`get_trigger`**              | Read             | Fetch a trigger's full configuration                                                         |
| **`describe_trigger_kickoff`** | Read             | List the available kickoff types, or describe one kickoff's supported conditions and actions |
| **`describe_trigger_action`**  | Read             | List the available action types, or describe one action's variables and compatible kickoffs  |
| **`get_trigger_examples`**     | Read             | Example payloads for common trigger patterns                                                 |
| **`validate_trigger`**         | Read             | Validate a `save_trigger` payload without saving it                                          |
| **`save_trigger`**             | Write            | Create a disabled trigger, or replace an existing trigger's configuration                    |

#### **Macros**

Discover saved macros, create or edit their message text, and delete them. Reading macro details requires permission to view macro settings; saving and deleting require permission to edit macro settings and the macro itself.

| **Tool**           | **Read / Write** | **Description**                                                                            |
| ------------------ | ---------------- | ------------------------------------------------------------------------------------------ |
| **`list_macros`**  | Read             | List visible macro summaries and groups, with optional name search and group filtering     |
| **`get_macro`**    | Read             | Read stored HTML, text type, visibility, configured action types, and attachment summaries |
| **`save_macro`**   | Write            | Create a text-only macro or edit an existing macro's name, message text, or text type      |
| **`delete_macro`** | Write            | Permanently delete a macro, including its actions and attachments                          |

`list_macros` accepts `query`, `macro_group_id`, `limit` (default 25, maximum 100), and `cursor`. Continue with the returned cursor and the same filters when `has_next_page` is true.

To create a macro, provide `name`, `macro_group_id` from `list_macros`, and either Markdown `text` or HTML `text_html`. New macros are organization-visible and default to the `reply` text type; `note` and `email` are also supported.

To edit a macro, first call `get_macro`, then supply its `macro_id` and only the fields you want to change. Use `text_html` when editing returned HTML to preserve rich formatting and template metadata. `text` and `text_html` are mutually exclusive and both are sanitized. Explicitly empty content, or content with neither text nor a safe image after sanitization, is rejected. Omit both to preserve existing message text.

Existing actions, conditions, visibility, editor permissions, group, and attachments are preserved. Change those settings or remove files in Pylon. Attachment summaries are read-only and limited to 100 entries; check `attachment_count` and `has_more_attachments` for additional files. These tools do not execute macros, resolve template variables against an issue, or send messages.

`delete_macro` takes a `macro_id` from `list_macros`. Deleting a macro can't be undone.

#### **Filters, Fields & Tags**

These tools help an AI tool build valid filters and field values for the tools above, and manage tag definitions.

| **Tool**                    | **Read / Write** | **Description**                                                                                                      |
| --------------------------- | ---------------- | -------------------------------------------------------------------------------------------------------------------- |
| **`build_filter`**          | Read             | Build a validated filter for any object type                                                                         |
| **`get_filter_attributes`** | Read             | Fields, operators, and reference types available when filtering an object type                                       |
| **`get_custom_fields`**     | Read             | List custom field definitions for an object type                                                                     |
| **`get_ticket_forms`**      | Read             | List your ticket forms, or get one, with each form's fields, required and hidden settings, and visibility conditions |
| **`list_tags`**             | Read             | List issue, account, or knowledge base article tags, or look one up by exact value                                   |
| **`save_tag`**              | Write            | Create a tag, or rename or recolor an existing tag                                                                   |
| **`delete_tag`**            | Write            | Permanently delete a tag and remove it from everything it's applied to                                               |

For custom-field filters or updates, use `get_custom_fields` to discover the field definitions and valid values first. Use `get_filter_attributes` and `build_filter` for filters beyond a search tool's direct arguments. Pass the returned `filter_json` to search tools that accept it, such as `search_issues`.

Search tools use the argument names shown in their schemas. Some accept common aliases, but use the documented names for new integrations. For paginated tools, continue with the returned `cursor` while keeping your filters unchanged, and stop when `has_next_page` is false.

Check `search_issues` response warnings before interpreting an empty result. An unmatched account, assignee, or requester name means the name lookup found no record; it does not confirm that the intended account or person has no matching issues. Follow the warning's recovery guidance and retry the search.

Saving and deleting a tag requires permission to edit issue tags, account tags, or the knowledge base, depending on the tag's `object_type` (`issue`, `account`, or `article`).

For `save_tag`, omit `tag_id` to create a tag with `object_type` and `value`, and optionally a `color`. Tag values are unique per object type and compared case-insensitively, so check `list_tags` first and reuse an existing tag. To rename or recolor a tag, supply its `tag_id`, its `object_type`, and the `value` or `color` to change. Renaming a tag changes it everywhere it's applied. To add or remove tags on a single issue, account, or knowledge base article, use `update_issue`, `update_account`, or `update_article_settings` instead.

`delete_tag` permanently deletes a tag and removes it from every issue, account, or article it's applied to. It can't be undone. If a trigger, view, dashboard, macro, or other configuration still uses the tag, the deletion is refused and the error lists what uses it. Remove the tag from those in Pylon, then try again.

#### **Audit Logs**

Requires Admin permission. Full audit log history is available on the Enterprise plan; otherwise, searches cover only the last 30 days. A search starting earlier than that limit returns an error.

| **Tool**                     | **Read / Write** | **Description**                                                                      |
| ---------------------------- | ---------------- | ------------------------------------------------------------------------------------ |
| **`list_audit_log_actions`** | Read             | Discover exact supported action names, regardless of recorded events                 |
| **`search_audit_logs`**      | Read             | Search recorded actions and changes in your organization by object, action, and time |

Use `object_id` to find changes to an issue or account. Resolve a ticket number to its ID with `get_issue` first. Use `actions` for exact action names or `action_contains` to discover names by substring. `happened_after` and `happened_before` accept RFC3339 timestamps, such as `2026-10-01T00:00:00Z`. Filters combine with AND; within `actions`, an entry can match any supplied action. Actor IDs are returned, but actor filtering is not supported.

Results include `audit_logs`, the current page's `count`, and `has_next_page`. The default `limit` is 25 and the maximum is 100. Continue with the returned `cursor` and unchanged filters. Set `include_metadata` to `true` for action-specific details; metadata is omitted by default. When history is restricted, `history_limited_to_days` is `30`.

**Find action names**

Call `list_audit_log_actions` for the authoritative catalog of action names supported by audit-log search. It includes names regardless of whether matching events exist in your workspace and excludes hidden actions. It requires the same Admin permission as `search_audit_logs`.

Use optional `query` for a case-insensitive substring match on names. Results are alphabetical; `limit` defaults to 50 and has a maximum of 100. Continue with the returned `cursor` and unchanged `query` while `has_next_page` is true to read the full catalog. The `count` is the number of names on the current page.

The `actions` filter takes exact strings from this catalog or a returned entry's `action` field. Copy those values rather than guessing from a UI label: some stored action names differ from the labels shown in Pylon.

Common exact action names include:

| Change                               | Exact action name             |
| ------------------------------------ | ----------------------------- |
| One issue custom field changed       | `Issue Custom Field Updated`  |
| Multiple issue custom fields changed | `Issue Custom Fields Updated` |
| Issue assigned                       | `Success Issue Assigned`      |
| Issue closed                         | `Success Ticket Closed`       |
| Issue tags changed                   | `Issue Tags Changed`          |
| Account owner changed                | `Account Owner Changed`       |
| Account created                      | `Account Created`             |
| Macro edited                         | `Macro Updated`               |

For example, call `list_audit_log_actions` to discover custom-field action names:

```json
{
  "query": "Custom Field",
  "limit": 50
}
```

Then copy returned names into `search_audit_logs.actions`:

```json
{
  "actions": ["Issue Custom Field Updated", "Issue Custom Fields Updated"],
  "include_metadata": true,
  "limit": 25
}
```

These are examples, not a complete catalog. Use `list_audit_log_actions` for the full catalog. A listed action may have no recorded events in your workspace; search results remain subject to your history access. In `search_audit_logs`, `action_contains` searches action names only, not attributes, field values, or metadata.

Audit logs show recorded events, not a complete explanation of every automation or field change.

#### **Contact Pylon Support**

| **Tool**                    | **Read / Write** | **Description**                                        |
| --------------------------- | ---------------- | ------------------------------------------------------ |
| **`submit_support_ticket`** | Write            | Send a request about Pylon to Pylon's own support team |

Sign in as a human Pylon user with an email address. Before submission, your AI tool must obtain your agreement to send the request specifically to Pylon support. Use `create_issue` for tickets in your own workspace. Share only relevant approved context, and reuse the same `idempotency_key` and unchanged request details when retrying a submission to avoid duplicates.

#### AI Agents

AI agent backtesting through MCP requires AI Agents and Backtesting for your organization, plus MCP Access and the relevant agent permissions. `get_agent_issue` needs permission to view AI agents. Issue-backed cases and agent activity follow your issue visibility.

| Tool                                 | Read / Write | Description                                                                                                      |
| ------------------------------------ | ------------ | ---------------------------------------------------------------------------------------------------------------- |
| **`list_agents`**                    | Read         | Find the AI agent ID to test.                                                                                    |
| **`list_agent_variations`**          | Read         | Find customer-visible variation IDs for an agent.                                                                |
| **`list_backtest_datasets`**         | Read         | Find datasets and their case counts.                                                                             |
| **`create_backtest_dataset`**        | Write        | Create an empty dataset.                                                                                         |
| **`add_issues_to_backtest_dataset`** | Write        | Snapshot readable issues as cases (up to 100 per dataset).                                                       |
| **`run_backtest`**                   | Write        | Start asynchronous runs for one or more agent configurations.                                                    |
| **`list_backtests`**                 | Read         | Find customer backtests, their runs, and progress.                                                               |
| **`get_backtest_results`**           | Read         | Get paginated progress and results for a backtest or run.                                                        |
| **`get_backtest_case`**              | Read         | Compare every agent result for one case.                                                                         |
| **`get_playground`**                 | Read         | Inspect the full message, tool, and event timeline for a result.                                                 |
| **`get_agent_issue`**                | Read         | See an AI agent's full activity on a real issue: tool calls, runbook steps, escalations, messages, and outcomes. |
| **`update_backtest_case_feedback`**  | Write        | Rate one case result thumbs up or thumbs down, or clear its rating.                                              |

#### **REST API**

When no other tool does what you need, AI tools can run operations from the [Pylon REST API](https://docs.usepylon.com/pylon-docs/developer/api) directly. Each call runs as the authenticated user, so the operation's own permission checks apply, just as they do in the Pylon dashboard.

| **Tool**                    | **Read / Write** | **Description**                                                   |
| --------------------------- | ---------------- | ----------------------------------------------------------------- |
| **`search_api_operations`** | Read             | Find REST API operations by keyword, and which tool runs each one |
| **`get_api_operation`**     | Read             | Get an operation's argument schema and response shape             |
| **`call_api_read`**         | Read             | Run a read-only operation, such as a get or a search              |
| **`call_api_write`**        | Write            | Run an operation that creates, updates, or deletes data           |

An AI tool finds an operation with `search_api_operations`, gets its arguments with `get_api_operation`, then runs it with the tool named in the result. Finding an operation doesn't run it. Reads and searches run through `call_api_read`, and changes run through `call_api_write`, so you can require approval for writes only in your AI tool.

Writes apply immediately and can be visible to customers. Some updates replace a whole list, such as an account's tags, so read the current value first and send the full list. Writes have no idempotency key: if a write's outcome is unknown, read the record before retrying.

Pass `select`, a [JMESPath](https://jmespath.org) expression, to return only the fields you need, such as `data[].{id: id, name: name}`. Read responses over 200 KB return an error; narrow them with `select` or request fewer results. If a write's response is over 200 KB, the write still succeeds and returns a short note instead of the response, so don't retry it.

Each operation uses its REST API [rate limit](https://docs.usepylon.com/pylon-docs/developer/api/rate-limits). When an operation is throttled, the error says how many seconds to wait.

These operations aren't available through MCP:

* Creating or importing contacts, sending customer portal invitations, and setting a contact's portal role
* Importing issues, messages, projects, and tasks
* Updating users, including roles and deactivation
* File uploads

The REST API tools aren't available in the published Pylon app for ChatGPT. Custom ChatGPT connectors include them.

### **Combined tools**

Some tools were combined to keep the list short for AI tools. Use the replacement names below for new integrations and migrate scripts that use old names. Old names marked *(removed)* no longer work. The others remain callable but are hidden from tool discovery.

| **Old tool**                                                                                                                                                                             | **Use instead**                                                    |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ |
| `create_task`                                                                                                                                                                            | `save_task` without `task_id`                                      |
| `update_task`                                                                                                                                                                            | `save_task` with `task_id`                                         |
| `create_contact` *(removed)*                                                                                                                                                             | `save_contact` without `contact_id`                                |
| `update_contact`                                                                                                                                                                         | `save_contact` with `contact_id`                                   |
| `create_feature_request`, `update_feature_request` *(removed)*                                                                                                                           | `save_feature_request` without or with `feature_request_id`        |
| `create_project` *(removed)*                                                                                                                                                             | `save_project` without `project_id`                                |
| `update_project`                                                                                                                                                                         | `save_project` with `project_id`                                   |
| `create_milestone` *(removed)*                                                                                                                                                           | `save_milestone` without `milestone_id`                            |
| `update_milestone` *(removed)*                                                                                                                                                           | `save_milestone` with `milestone_id`                               |
| `create_account_note` *(removed)*                                                                                                                                                        | `save_account_note` without `note_id`                              |
| `update_account_note` *(removed)*                                                                                                                                                        | `save_account_note` with `note_id`                                 |
| `get_notebook_content` *(removed)*                                                                                                                                                       | `get_account_notes` for a Notes block                              |
| `create_trigger` *(removed)*, `update_trigger`                                                                                                                                           | `save_trigger`                                                     |
| `list_trigger_kickoffs`, `list_trigger_actions` *(removed)*                                                                                                                              | `describe_trigger_kickoff`, `describe_trigger_action` with no type |
| `get_issue_filter_attributes`, `get_account_filter_attributes`                                                                                                                           | `get_filter_attributes` with `object_type`                         |
| `get_contact_filter_attributes`, `get_task_filter_attributes`, `get_project_filter_attributes`, `get_opportunity_filter_attributes`, `get_feature_request_filter_attributes` *(removed)* | `get_filter_attributes` with `object_type`                         |
| `get_tasks`, `get_projects`                                                                                                                                                              | `search_tasks`, `search_projects`                                  |
| `create_project_from_template` *(removed)*                                                                                                                                               | `save_project` with `project_template_id` (omit `project_id`)      |
| `get_milestone` *(removed)*                                                                                                                                                              | `get_milestones` with `milestone_id`                               |
| `get_article_by_identifier` *(removed)*                                                                                                                                                  | `get_article` with `identifier`                                    |
| `create_draft_article`, `create_draft_article_version` *(removed)*                                                                                                                       | `save_draft_article`                                               |
| `list_teams`                                                                                                                                                                             | `search_teams`                                                     |
| `get_tag`                                                                                                                                                                                | `list_tags` with `value`                                           |

### **Rate limits**

Rate limits are applied per tool and per organization to keep the MCP server healthy under bursty AI traffic. Tool throttling returns a JSON-RPC error with code **`-32000`**. Its message identifies the tool and tells you how many seconds to wait before retrying. Wait for that delay before retrying the call.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.usepylon.com/pylon-docs/integrations/pylon-mcp.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
