diff --git a/app/en/mcp-servers/customer-support/_meta.tsx b/app/en/mcp-servers/customer-support/_meta.tsx
index ec6ce7446..192bec491 100644
--- a/app/en/mcp-servers/customer-support/_meta.tsx
+++ b/app/en/mcp-servers/customer-support/_meta.tsx
@@ -11,6 +11,9 @@ const meta: MetaRecord = {
zendesk: {
title: "Zendesk",
},
+ pylon: {
+ title: "Pylon",
+ },
};
export default meta;
diff --git a/app/en/mcp-servers/customer-support/pylon/page.mdx b/app/en/mcp-servers/customer-support/pylon/page.mdx
new file mode 100644
index 000000000..5d734c77d
--- /dev/null
+++ b/app/en/mcp-servers/customer-support/pylon/page.mdx
@@ -0,0 +1,518 @@
+# Pylon
+
+import ToolInfo from "@/app/_components/tool-info";
+import Badges from "@/app/_components/badges";
+import TabbedCodeBlock from "@/app/_components/tabbed-code-block";
+import TableOfContents from "@/app/_components/table-of-contents";
+import ToolFooter from "@/app/_components/tool-footer";
+import { Callout } from "nextra/components";
+
+
+
+
+
+The Pylon MCP Server lets agents work with Pylon’s issue management features—list and search issues, assign owners, add messages, browse contacts, users, and teams. There is **no OAuth** for Pylon; you must provide an **admin-generated API token**.
+
+- **Issues**: list, search (BM25), fetch details, assign owners, update status, add messages
+- **Contacts**: list and search by name or email
+- **Users & Teams**: list/search users, list teams, get team details with members
+- **User context**: fetch the API token owner profile (service account)
+
+
+ Pylon API tokens are admin-scoped and created in Pylon by an org admin. Store
+ the token as `PYLON_API_TOKEN` in Arcade secrets. There is no user OAuth.
+
+
+## Available tools
+
+
+
+
+ If you need a tool that isn't listed, [contact us](mailto:contact@arcade.dev)
+ or [build your own](/home/build-tools/create-a-mcp-server).
+
+
+
+ - `readOnlyHint` — reads data only - `openWorldHint` — calls Pylon’s external
+ API - `destructiveHint` — flags irreversible or hidden changes -
+ `idempotentHint` — repeating the same call has no extra effect
+
+
+---
+
+## User context
+
+### Pylon.WhoAmI
+
+Get the API token owner (service account) profile.
+
+
+
+Returns name, email, and org info for the token owner.
+
+**Parameters**
+
+This tool takes no parameters.
+
+
+ - `readOnlyHint: true` - `openWorldHint: true`
+
+
+
+ GET `/me`
+
+
+---
+
+## Issue tools
+
+### Pylon.ListIssues
+
+List issues with optional filters.
+
+
+
+**Parameters**
+
+- **state** (`enum`, _optional_) Filter by state.
+- **assignee_id** (`string`, _optional_) Filter by assignee ID.
+- **team_id** (`string`, _optional_) Filter by team ID.
+- **tags** (`array`, _optional_) Issues must include all provided tags.
+- **start_time** (`string`, _optional_) RFC3339 start time. Default: 7 days ago.
+- **end_time** (`string`, _optional_) RFC3339 end time. Default: now.
+- **cursor** (`string`, _optional_) Pagination cursor.
+
+
+ GET `/issues`
+
+
+---
+
+### Pylon.GetIssue
+
+Get detailed issue info by ID or keyword search (BM25).
+
+
+
+**Parameters**
+
+- **lookup_by** (`enum`, **required**) `id` or `search`.
+- **value** (`string`, **required**) Issue ID/number or search keywords.
+- **auto_accept_matches** (`boolean`, _optional_) Auto-accept search matches above confidence threshold. Default: `false`.
+
+
+ GET `/issues/{id}` or GET `/issues` (search)
+
+
+---
+
+### Pylon.SearchIssues
+
+Keyword search across recent issues (BM25).
+
+
+
+**Parameters**
+
+- **query** (`string`, **required**) Keywords (supports AND/OR/NOT).
+- **auto_accept_matches** (`boolean`, _optional_) Auto-accept high-confidence matches. Default: `false`.
+
+
+ GET `/issues` (fetch recent issues for ranking)
+
+
+---
+
+### Pylon.AssignIssue
+
+Assign an issue to a user (ID or fuzzy name).
+
+
+
+**Parameters**
+
+- **issue_lookup_by** (`enum`, **required**) `id` or `search`.
+- **issue_value** (`string`, **required**) Issue ID/number or search keywords.
+- **user_lookup_by** (`enum`, **required**) `id` or `name`.
+- **user_value** (`string`, **required**) User ID or name (fuzzy match).
+- **auto_accept_matches** (`boolean`, _optional_) Auto-accept fuzzy/BM25 matches. Default: `false`.
+
+
+ GET `/issues/{id}`, GET `/issues`, GET `/users`, PATCH `/issues/{id}`
+
+
+---
+
+### Pylon.UpdateIssueStatus
+
+Change the state of an issue.
+
+
+
+**Parameters**
+
+- **state** (`enum`, **required**) New state.
+- **lookup_by** (`enum`, **required**) `id` or `search`.
+- **value** (`string`, **required**) Issue ID/number or keywords.
+- **auto_accept_matches** (`boolean`, _optional_) Auto-accept search matches. Default: `false`.
+
+
+ GET `/issues/{id}`, GET `/issues`, PATCH `/issues/{id}`
+
+
+---
+
+### Pylon.AddMessage
+
+Add an internal note to an issue.
+
+
+
+**Parameters**
+
+- **issue_id** (`string`, **required**) Issue ID or number.
+- **body** (`string`, **required**) Message content.
+- **as_html** (`boolean`, _optional_) Body is pre-formatted HTML. Default: `false`.
+
+
+ POST `/issues/{id}/note`
+
+
+---
+
+## Contact tools
+
+### Pylon.ListContacts
+
+List contacts with pagination.
+
+
+
+**Parameters**
+
+- **cursor** (`string`, _optional_) Pagination cursor.
+
+
+ GET `/contacts`
+
+
+---
+
+### Pylon.SearchContacts
+
+Search contacts by name or email.
+
+
+
+**Parameters**
+
+- **query** (`string`, **required**) Name or email.
+- **auto_accept_matches** (`boolean`, _optional_) Auto-accept matches above confidence threshold. Default: `false`.
+
+
+ POST `/contacts/search`, GET `/contacts`
+
+
+---
+
+## User tools
+
+### Pylon.ListUsers
+
+List users in the workspace.
+
+
+
+**Parameters**
+
+- **cursor** (`string`, _optional_) Pagination cursor.
+- **limit** (`integer`, _optional_) Items per page. Default: 20.
+
+
+ GET `/users`
+
+
+---
+
+### Pylon.SearchUsers
+
+Search users by name (fuzzy).
+
+
+
+**Parameters**
+
+- **query** (`string`, **required**) Name or partial name.
+- **auto_accept_matches** (`boolean`, _optional_) Auto-accept matches above confidence threshold. Default: `false`.
+
+
+ GET `/users`
+
+
+---
+
+## Team tools
+
+### Pylon.ListTeams
+
+List teams in the workspace.
+
+
+
+**Parameters**
+
+- **cursor** (`string`, _optional_) Pagination cursor.
+
+
+ GET `/teams`
+
+
+---
+
+### Pylon.GetTeamAndAssignment
+
+Get team details (with members) by ID or fuzzy name.
+
+
+
+**Parameters**
+
+- **lookup_by** (`enum`, **required**) `id` or `name`.
+- **value** (`string`, **required**) Team ID or name.
+- **auto_accept_matches** (`boolean`, _optional_) Auto-accept fuzzy matches. Default: `false`.
+
+
+ GET `/teams`, GET `/teams/{id}`
+
+
+---
+
+## Auth
+
+Pylon uses Bearer tokens created by an org admin. There is **no OAuth flow**. Generate an API token in the Pylon dashboard and store it as the secret `PYLON_API_TOKEN` in Arcade. All tools require this secret.
+
+**Auth header**
+
+```
+Authorization: Bearer
+```
+
+
+ Pylon tokens are generated by admins in the Pylon UI and grant org-level
+ access. Rotate tokens regularly and scope storage to your Arcade project’s
+ secrets.
+
+
+Refer to Pylon’s authentication docs: [Pylon API Authentication](https://docs.usepylon.com/pylon-docs/developer/api/authentication).
+
+
diff --git a/public/examples/integrations/mcp-servers/pylon/add_message_example_call_tool.js b/public/examples/integrations/mcp-servers/pylon/add_message_example_call_tool.js
new file mode 100644
index 000000000..5f213d479
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/pylon/add_message_example_call_tool.js
@@ -0,0 +1,20 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade();
+const USER_ID = "{arcade_user_id}";
+const TOOL_NAME = "Pylon.AddMessage";
+
+const toolInput = {
+ issue_id: "ISSUE_ID_OR_NUMBER",
+ body: "Following up on this issue.",
+ as_html: false,
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+ secrets: { PYLON_API_TOKEN: "" },
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
diff --git a/public/examples/integrations/mcp-servers/pylon/add_message_example_call_tool.py b/public/examples/integrations/mcp-servers/pylon/add_message_example_call_tool.py
new file mode 100644
index 000000000..47c9a83d7
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/pylon/add_message_example_call_tool.py
@@ -0,0 +1,22 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade()
+
+USER_ID = "{arcade_user_id}"
+TOOL_NAME = "Pylon.AddMessage"
+
+tool_input = {
+ "issue_id": "ISSUE_ID_OR_NUMBER",
+ "body": "Following up on this issue.",
+ "as_html": False,
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+ secrets={"PYLON_API_TOKEN": ""},
+)
+
+print(json.dumps(response.output.value, indent=2))
diff --git a/public/examples/integrations/mcp-servers/pylon/assign_issue_example_call_tool.js b/public/examples/integrations/mcp-servers/pylon/assign_issue_example_call_tool.js
new file mode 100644
index 000000000..eee8a0661
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/pylon/assign_issue_example_call_tool.js
@@ -0,0 +1,22 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade();
+const USER_ID = "{arcade_user_id}";
+const TOOL_NAME = "Pylon.AssignIssue";
+
+const toolInput = {
+ issue_lookup_by: "id", // "id" or "search"
+ issue_value: "ISSUE_ID_OR_KEYWORDS",
+ user_lookup_by: "name", // "id" or "name"
+ user_value: "Alex Doe",
+ auto_accept_matches: false,
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+ secrets: { PYLON_API_TOKEN: "" },
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
diff --git a/public/examples/integrations/mcp-servers/pylon/assign_issue_example_call_tool.py b/public/examples/integrations/mcp-servers/pylon/assign_issue_example_call_tool.py
new file mode 100644
index 000000000..eb40e3630
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/pylon/assign_issue_example_call_tool.py
@@ -0,0 +1,24 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade()
+
+USER_ID = "{arcade_user_id}"
+TOOL_NAME = "Pylon.AssignIssue"
+
+tool_input = {
+ "issue_lookup_by": "id", # "id" or "search"
+ "issue_value": "ISSUE_ID_OR_KEYWORDS",
+ "user_lookup_by": "name", # "id" or "name"
+ "user_value": "Alex Doe",
+ "auto_accept_matches": False,
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+ secrets={"PYLON_API_TOKEN": ""},
+)
+
+print(json.dumps(response.output.value, indent=2))
diff --git a/public/examples/integrations/mcp-servers/pylon/get_issue_example_call_tool.js b/public/examples/integrations/mcp-servers/pylon/get_issue_example_call_tool.js
new file mode 100644
index 000000000..479f474d6
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/pylon/get_issue_example_call_tool.js
@@ -0,0 +1,20 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade();
+const USER_ID = "{arcade_user_id}";
+const TOOL_NAME = "Pylon.GetIssue";
+
+const toolInput = {
+ lookup_by: "id", // "id" or "search"
+ value: "ISSUE_ID_OR_KEYWORDS",
+ auto_accept_matches: false,
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+ secrets: { PYLON_API_TOKEN: "" },
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
diff --git a/public/examples/integrations/mcp-servers/pylon/get_issue_example_call_tool.py b/public/examples/integrations/mcp-servers/pylon/get_issue_example_call_tool.py
new file mode 100644
index 000000000..fd2b76b4b
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/pylon/get_issue_example_call_tool.py
@@ -0,0 +1,22 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade()
+
+USER_ID = "{arcade_user_id}"
+TOOL_NAME = "Pylon.GetIssue"
+
+tool_input = {
+ "lookup_by": "id", # "id" or "search"
+ "value": "ISSUE_ID_OR_KEYWORDS",
+ "auto_accept_matches": False,
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+ secrets={"PYLON_API_TOKEN": ""},
+)
+
+print(json.dumps(response.output.value, indent=2))
diff --git a/public/examples/integrations/mcp-servers/pylon/get_team_and_assignment_example_call_tool.js b/public/examples/integrations/mcp-servers/pylon/get_team_and_assignment_example_call_tool.js
new file mode 100644
index 000000000..9dfd67867
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/pylon/get_team_and_assignment_example_call_tool.js
@@ -0,0 +1,20 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade();
+const USER_ID = "{arcade_user_id}";
+const TOOL_NAME = "Pylon.GetTeamAndAssignment";
+
+const toolInput = {
+ lookup_by: "id", // "id" or "name"
+ value: "TEAM_ID_OR_NAME",
+ auto_accept_matches: false,
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+ secrets: { PYLON_API_TOKEN: "" },
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
diff --git a/public/examples/integrations/mcp-servers/pylon/get_team_and_assignment_example_call_tool.py b/public/examples/integrations/mcp-servers/pylon/get_team_and_assignment_example_call_tool.py
new file mode 100644
index 000000000..dc71cbf88
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/pylon/get_team_and_assignment_example_call_tool.py
@@ -0,0 +1,22 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade()
+
+USER_ID = "{arcade_user_id}"
+TOOL_NAME = "Pylon.GetTeamAndAssignment"
+
+tool_input = {
+ "lookup_by": "id", # "id" or "name"
+ "value": "TEAM_ID_OR_NAME",
+ "auto_accept_matches": False,
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+ secrets={"PYLON_API_TOKEN": ""},
+)
+
+print(json.dumps(response.output.value, indent=2))
diff --git a/public/examples/integrations/mcp-servers/pylon/list_contacts_example_call_tool.js b/public/examples/integrations/mcp-servers/pylon/list_contacts_example_call_tool.js
new file mode 100644
index 000000000..651fa5d53
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/pylon/list_contacts_example_call_tool.js
@@ -0,0 +1,18 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade();
+const USER_ID = "{arcade_user_id}";
+const TOOL_NAME = "Pylon.ListContacts";
+
+const toolInput = {
+ cursor: null,
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+ secrets: { PYLON_API_TOKEN: "" },
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
diff --git a/public/examples/integrations/mcp-servers/pylon/list_contacts_example_call_tool.py b/public/examples/integrations/mcp-servers/pylon/list_contacts_example_call_tool.py
new file mode 100644
index 000000000..67681aff6
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/pylon/list_contacts_example_call_tool.py
@@ -0,0 +1,20 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade()
+
+USER_ID = "{arcade_user_id}"
+TOOL_NAME = "Pylon.ListContacts"
+
+tool_input = {
+ "cursor": None,
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+ secrets={"PYLON_API_TOKEN": ""},
+)
+
+print(json.dumps(response.output.value, indent=2))
diff --git a/public/examples/integrations/mcp-servers/pylon/list_issues_example_call_tool.js b/public/examples/integrations/mcp-servers/pylon/list_issues_example_call_tool.js
new file mode 100644
index 000000000..665936fab
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/pylon/list_issues_example_call_tool.js
@@ -0,0 +1,24 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade();
+const USER_ID = "{arcade_user_id}";
+const TOOL_NAME = "Pylon.ListIssues";
+
+const toolInput = {
+ state: null,
+ assignee_id: null,
+ team_id: null,
+ tags: null,
+ start_time: null,
+ end_time: null,
+ cursor: null,
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+ secrets: { PYLON_API_TOKEN: "" },
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
diff --git a/public/examples/integrations/mcp-servers/pylon/list_issues_example_call_tool.py b/public/examples/integrations/mcp-servers/pylon/list_issues_example_call_tool.py
new file mode 100644
index 000000000..89afd57e9
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/pylon/list_issues_example_call_tool.py
@@ -0,0 +1,26 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade()
+
+USER_ID = "{arcade_user_id}"
+TOOL_NAME = "Pylon.ListIssues"
+
+tool_input = {
+ "state": None, # e.g., "open", "closed"
+ "assignee_id": None,
+ "team_id": None,
+ "tags": None,
+ "start_time": None,
+ "end_time": None,
+ "cursor": None,
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+ secrets={"PYLON_API_TOKEN": ""},
+)
+
+print(json.dumps(response.output.value, indent=2))
diff --git a/public/examples/integrations/mcp-servers/pylon/list_teams_example_call_tool.js b/public/examples/integrations/mcp-servers/pylon/list_teams_example_call_tool.js
new file mode 100644
index 000000000..44307847b
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/pylon/list_teams_example_call_tool.js
@@ -0,0 +1,18 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade();
+const USER_ID = "{arcade_user_id}";
+const TOOL_NAME = "Pylon.ListTeams";
+
+const toolInput = {
+ cursor: null,
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+ secrets: { PYLON_API_TOKEN: "" },
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
diff --git a/public/examples/integrations/mcp-servers/pylon/list_teams_example_call_tool.py b/public/examples/integrations/mcp-servers/pylon/list_teams_example_call_tool.py
new file mode 100644
index 000000000..00059b1fd
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/pylon/list_teams_example_call_tool.py
@@ -0,0 +1,20 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade()
+
+USER_ID = "{arcade_user_id}"
+TOOL_NAME = "Pylon.ListTeams"
+
+tool_input = {
+ "cursor": None,
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+ secrets={"PYLON_API_TOKEN": ""},
+)
+
+print(json.dumps(response.output.value, indent=2))
diff --git a/public/examples/integrations/mcp-servers/pylon/list_users_example_call_tool.js b/public/examples/integrations/mcp-servers/pylon/list_users_example_call_tool.js
new file mode 100644
index 000000000..7b950eab3
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/pylon/list_users_example_call_tool.js
@@ -0,0 +1,19 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade();
+const USER_ID = "{arcade_user_id}";
+const TOOL_NAME = "Pylon.ListUsers";
+
+const toolInput = {
+ cursor: null,
+ limit: 20,
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+ secrets: { PYLON_API_TOKEN: "" },
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
diff --git a/public/examples/integrations/mcp-servers/pylon/list_users_example_call_tool.py b/public/examples/integrations/mcp-servers/pylon/list_users_example_call_tool.py
new file mode 100644
index 000000000..38e52766d
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/pylon/list_users_example_call_tool.py
@@ -0,0 +1,21 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade()
+
+USER_ID = "{arcade_user_id}"
+TOOL_NAME = "Pylon.ListUsers"
+
+tool_input = {
+ "cursor": None,
+ "limit": 20,
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+ secrets={"PYLON_API_TOKEN": ""},
+)
+
+print(json.dumps(response.output.value, indent=2))
diff --git a/public/examples/integrations/mcp-servers/pylon/search_contacts_example_call_tool.js b/public/examples/integrations/mcp-servers/pylon/search_contacts_example_call_tool.js
new file mode 100644
index 000000000..8f1bdfe60
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/pylon/search_contacts_example_call_tool.js
@@ -0,0 +1,19 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade();
+const USER_ID = "{arcade_user_id}";
+const TOOL_NAME = "Pylon.SearchContacts";
+
+const toolInput = {
+ query: "alex@example.com",
+ auto_accept_matches: false,
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+ secrets: { PYLON_API_TOKEN: "" },
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
diff --git a/public/examples/integrations/mcp-servers/pylon/search_contacts_example_call_tool.py b/public/examples/integrations/mcp-servers/pylon/search_contacts_example_call_tool.py
new file mode 100644
index 000000000..adce5d4ba
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/pylon/search_contacts_example_call_tool.py
@@ -0,0 +1,21 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade()
+
+USER_ID = "{arcade_user_id}"
+TOOL_NAME = "Pylon.SearchContacts"
+
+tool_input = {
+ "query": "alex@example.com",
+ "auto_accept_matches": False,
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+ secrets={"PYLON_API_TOKEN": ""},
+)
+
+print(json.dumps(response.output.value, indent=2))
diff --git a/public/examples/integrations/mcp-servers/pylon/search_issues_example_call_tool.js b/public/examples/integrations/mcp-servers/pylon/search_issues_example_call_tool.js
new file mode 100644
index 000000000..6e6dc1dcb
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/pylon/search_issues_example_call_tool.js
@@ -0,0 +1,19 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade();
+const USER_ID = "{arcade_user_id}";
+const TOOL_NAME = "Pylon.SearchIssues";
+
+const toolInput = {
+ query: "login timeout",
+ auto_accept_matches: false,
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+ secrets: { PYLON_API_TOKEN: "" },
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
diff --git a/public/examples/integrations/mcp-servers/pylon/search_issues_example_call_tool.py b/public/examples/integrations/mcp-servers/pylon/search_issues_example_call_tool.py
new file mode 100644
index 000000000..6465da008
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/pylon/search_issues_example_call_tool.py
@@ -0,0 +1,21 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade()
+
+USER_ID = "{arcade_user_id}"
+TOOL_NAME = "Pylon.SearchIssues"
+
+tool_input = {
+ "query": "login timeout",
+ "auto_accept_matches": False,
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+ secrets={"PYLON_API_TOKEN": ""},
+)
+
+print(json.dumps(response.output.value, indent=2))
diff --git a/public/examples/integrations/mcp-servers/pylon/search_users_example_call_tool.js b/public/examples/integrations/mcp-servers/pylon/search_users_example_call_tool.js
new file mode 100644
index 000000000..8a7618780
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/pylon/search_users_example_call_tool.js
@@ -0,0 +1,19 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade();
+const USER_ID = "{arcade_user_id}";
+const TOOL_NAME = "Pylon.SearchUsers";
+
+const toolInput = {
+ query: "Alex",
+ auto_accept_matches: false,
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+ secrets: { PYLON_API_TOKEN: "" },
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
diff --git a/public/examples/integrations/mcp-servers/pylon/search_users_example_call_tool.py b/public/examples/integrations/mcp-servers/pylon/search_users_example_call_tool.py
new file mode 100644
index 000000000..e6c3c603e
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/pylon/search_users_example_call_tool.py
@@ -0,0 +1,21 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade()
+
+USER_ID = "{arcade_user_id}"
+TOOL_NAME = "Pylon.SearchUsers"
+
+tool_input = {
+ "query": "Alex",
+ "auto_accept_matches": False,
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+ secrets={"PYLON_API_TOKEN": ""},
+)
+
+print(json.dumps(response.output.value, indent=2))
diff --git a/public/examples/integrations/mcp-servers/pylon/update_issue_status_example_call_tool.js b/public/examples/integrations/mcp-servers/pylon/update_issue_status_example_call_tool.js
new file mode 100644
index 000000000..04dea21bf
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/pylon/update_issue_status_example_call_tool.js
@@ -0,0 +1,21 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade();
+const USER_ID = "{arcade_user_id}";
+const TOOL_NAME = "Pylon.UpdateIssueStatus";
+
+const toolInput = {
+ state: "open", // e.g., "open", "closed"
+ lookup_by: "id", // "id" or "search"
+ value: "ISSUE_ID_OR_KEYWORDS",
+ auto_accept_matches: false,
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+ secrets: { PYLON_API_TOKEN: "" },
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
diff --git a/public/examples/integrations/mcp-servers/pylon/update_issue_status_example_call_tool.py b/public/examples/integrations/mcp-servers/pylon/update_issue_status_example_call_tool.py
new file mode 100644
index 000000000..fdec2b69c
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/pylon/update_issue_status_example_call_tool.py
@@ -0,0 +1,23 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade()
+
+USER_ID = "{arcade_user_id}"
+TOOL_NAME = "Pylon.UpdateIssueStatus"
+
+tool_input = {
+ "state": "open", # e.g., "open", "closed"
+ "lookup_by": "id", # "id" or "search"
+ "value": "ISSUE_ID_OR_KEYWORDS",
+ "auto_accept_matches": False,
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+ secrets={"PYLON_API_TOKEN": ""},
+)
+
+print(json.dumps(response.output.value, indent=2))
diff --git a/public/examples/integrations/mcp-servers/pylon/who_am_i_example_call_tool.js b/public/examples/integrations/mcp-servers/pylon/who_am_i_example_call_tool.js
new file mode 100644
index 000000000..d172d0413
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/pylon/who_am_i_example_call_tool.js
@@ -0,0 +1,14 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade();
+const USER_ID = "{arcade_user_id}";
+const TOOL_NAME = "Pylon.WhoAmI";
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: {},
+ user_id: USER_ID,
+ secrets: { PYLON_API_TOKEN: "" },
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
diff --git a/public/examples/integrations/mcp-servers/pylon/who_am_i_example_call_tool.py b/public/examples/integrations/mcp-servers/pylon/who_am_i_example_call_tool.py
new file mode 100644
index 000000000..e0aa337be
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/pylon/who_am_i_example_call_tool.py
@@ -0,0 +1,16 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade()
+
+USER_ID = "{arcade_user_id}"
+TOOL_NAME = "Pylon.WhoAmI"
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input={},
+ user_id=USER_ID,
+ secrets={"PYLON_API_TOKEN": ""},
+)
+
+print(json.dumps(response.output.value, indent=2))