diff --git a/app/en/home/auth-providers/linear/page.mdx b/app/en/home/auth-providers/linear/page.mdx
index 2615230ec..aa7c8667e 100644
--- a/app/en/home/auth-providers/linear/page.mdx
+++ b/app/en/home/auth-providers/linear/page.mdx
@@ -4,14 +4,20 @@ import { Tabs, Callout, Steps } from "nextra/components";
The Linear auth provider enables tools and agents to call [Linear APIs](https://linear.app/developers/graphql) on behalf of a user.
+
+ Want to quickly get started with Linear in your agent or AI app? The pre-built
+ [Arcade Linear MCP Server](/mcp-servers/productivity/linear) is what you want!
+
+
### What's documented here
This page describes how to use and configure Linear auth with Arcade.
This auth provider is used by:
-- Your [app code](#using-linear-auth-in-app-code) that needs to call the Linear API
-- Or, your [custom tools](#using-Linear-auth-in-custom-tools) that need to call the Linear API
+- The [Arcade Linear MCP Server](/mcp-servers/productivity/linear), which provides pre-built tools for interacting with Linear
+- Your [app code](#using-linear-auth-in-app-code) that needs to call Linear APIs
+- Or, your [custom tools](#using-linear-auth-in-custom-tools) that need to call Linear APIs
## Configuring Linear auth
@@ -25,24 +31,22 @@ This auth provider is used by:
In a production environment, you will most likely want to use your own Linear app credentials. This way, your users will see your application's name requesting permission.
-
Before showing how to configure your Linear app credentials, let's go through the steps to create a Linear app.
### Create a Linear app
-- It is **highly recommended** to first [create a new Linear workspace](https://linear.app/join) for the purpose of managing the OAuth2 Application.
-- Create a new public OAuth2 Application in your [integration's settings page](https://linear.app/settings/api/applications/new).
-- Fill out your application specific information such as application name and description.
-- Set the Callback URL to the redirect URL generated by Arcade (see below)
-- Toggle the **Public** switch to enable public access to the application if you want other workspaces to be able to use your application.
-- Once you complete creating your integration, copy the client ID and client secret to use below.
+- It is **highly recommended** to first [create a new Linear workspace](https://linear.app/join) for the purpose of managing the OAuth2 Application, as each admin user will have access
+- Create a new public OAuth2 Application in your [integration settings page](https://linear.app/settings/api/applications/new)
+- Fill out your application specific information such as application name and description
+- Choose the [scopes](https://linear.app/developers/oauth-2-0-authentication#redirect-user-access-requests-to-linear) (permissions) you need for your app
+- Add the redirect URL generated by Arcade (see below) to the Callback URL field
+- Toggle the **Public** switch if you want other workspaces to be able to use your application
+- Copy the client ID and client secret to use below
Next, add the Linear app to Arcade.
## Configuring your own Linear Auth Provider in Arcade
-
-
@@ -66,7 +70,7 @@ To access the Arcade Cloud dashboard, go to [api.arcade.dev/dashboard](https://a
- Choose a unique **ID** for your provider (e.g. "my-linear-provider").
- Optionally enter a **Description**.
- Enter the **Client ID** and **Client Secret** from your Linear app.
-- Note the **Redirect URL** generated by Arcade. This must be set as your Linear app's Callback URL.
+- Note the **Redirect URL** generated by Arcade. This must be added to your Linear app's Callback URL field.
#### Create the provider
@@ -81,27 +85,38 @@ When you use tools that require Linear auth using your Arcade account credential
## Using Linear auth in app code
-Use the Linear auth provider in your own agents and AI apps to get a user token for the Linear API. See [authorizing agents with Arcade](/home/auth/how-arcade-helps) to understand how this works.
+Use the Linear auth provider in your own agents and AI apps to get a user token for Linear APIs. See [authorizing agents with Arcade](/home/auth/how-arcade-helps) to understand how this works.
-Use `client.auth.start()` to get a user token for the Linear API:
+Use `client.auth.start()` to get a user token for Linear APIs:
-```python {8-14}
+```python {22-26}
from arcadepy import Arcade
+import httpx
client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
user_id = "{arcade_user_id}"
+"""
+In this example, we will use Arcade to authenticate with Linear and
+retrieve teams.
+
+There is a tool for that in the Arcade Linear MCP Server, which simplifies
+the process for you to interact with Linear either through our Python or
+JavaScript SDKs or via LLM tool calling.
+
+Below we are just showing how to use Arcade as an auth provider, if you ever
+need to.
+"""
+
# Start the authorization process
auth_response = client.auth.start(
user_id=user_id,
provider="linear",
- scopes=[
- "read"
- ],
+ scopes=["read"],
)
if auth_response.status != "completed":
@@ -112,20 +127,59 @@ if auth_response.status != "completed":
auth_response = client.auth.wait_for_completion(auth_response)
token = auth_response.context.token
-# Do something interesting with the token...
+
+if not token:
+ raise ValueError("No token found in auth response")
+
+# Use the Linear GraphQL API
+url = "https://api.linear.app/graphql"
+headers = {
+ "Authorization": f"Bearer {token}",
+ "Content-Type": "application/json",
+}
+
+query = """
+query Teams {
+ teams {
+ nodes {
+ id
+ name
+ key
+ }
+ }
+}
+"""
+
+response = httpx.post(url, json={"query": query}, headers=headers)
+data = response.json()
+teams = data["data"]["teams"]["nodes"]
+
+print(teams)
```
-```javascript {8-10}
+```javascript {20-22}
import { Arcade } from "@arcadeai/arcadejs";
const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
const userId = "{arcade_user_id}";
+/*
+In this example, we will use Arcade to authenticate with Linear and
+retrieve teams.
+
+There is a tool for that in the Arcade Linear MCP Server, which simplifies
+the process for you to interact with Linear either through our Python or
+JavaScript SDKs or via LLM tool calling.
+
+Below we are just showing how to use Arcade as an auth provider, if you ever
+need to.
+*/
+
// Start the authorization process
let authResponse = await client.auth.start(userId, "linear", {
scopes: ["read"],
@@ -139,8 +193,42 @@ if (authResponse.status !== "completed") {
// Wait for the authorization to complete
authResponse = await client.auth.waitForCompletion(authResponse);
+if (!authResponse.context.token) {
+ throw new Error("No token found in auth response");
+}
+
const token = authResponse.context.token;
-// Do something interesting with the token...
+
+// Use the Linear GraphQL API
+const response = await fetch("https://api.linear.app/graphql", {
+ method: "POST",
+ headers: {
+ Authorization: `Bearer ${token}`,
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({
+ query: `
+ query Teams {
+ teams {
+ nodes {
+ id
+ name
+ key
+ }
+ }
+ }
+ `,
+ }),
+});
+
+if (!response.ok) {
+ throw new Error(`HTTP error! status: ${response.status}`);
+}
+
+const data = await response.json();
+const teams = data.data.teams.nodes;
+
+console.log(teams);
```
@@ -155,7 +243,7 @@ If the pre-built tools in the Linear MCP Server don't meet your needs, you can a
Use the `Linear()` auth class to specify that a tool requires authorization with Linear. The `context.authorization.token` field will be automatically populated with the user's Linear token:
-```python
+```python {3-4,10-14,26}
from typing import Annotated, Any
from arcade_tdk import ToolContext, tool
@@ -165,14 +253,18 @@ import httpx
@tool(requires_auth=Linear(scopes=["read"]))
-async def get_teams(context: ToolContext) -> Annotated[dict[str, Any], "Teams in the workspace with member information"]:
+async def get_teams(
+ context: ToolContext,
+) -> Annotated[dict[str, Any], "Teams in the workspace with member information"]:
"""Get Linear teams and team information including team members"""
- token = context.get_auth_token_or_empty()
+ if not context.authorization or not context.authorization.token:
+ raise ValueError("No token found in context")
+
+ token = context.authorization.token
url = "https://api.linear.app/graphql"
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
- "Accept": "application/json",
}
query = """
@@ -188,9 +280,9 @@ async def get_teams(context: ToolContext) -> Annotated[dict[str, Any], "Teams in
"""
async with httpx.AsyncClient() as client:
- resp = await client.post(url, json={"query": query}, headers=headers)
- resp.raise_for_status()
- data = resp.json()
- teams = data["data"]["teams"]["nodes"]
- return teams
+ resp = await client.post(url, json={"query": query}, headers=headers)
+ resp.raise_for_status()
+ data = resp.json()
+ teams = data["data"]["teams"]["nodes"]
+ return teams
```
diff --git a/app/en/mcp-servers/productivity/linear/page.mdx b/app/en/mcp-servers/productivity/linear/page.mdx
index 573eede30..a49f811ce 100644
--- a/app/en/mcp-servers/productivity/linear/page.mdx
+++ b/app/en/mcp-servers/productivity/linear/page.mdx
@@ -11,30 +11,86 @@ import { Callout } from "nextra/components";
description="Enable agents to interact with Linear"
author="Arcade"
authType="OAuth2"
- versions={["0.1.0"]}
+ versions={["2.0.0"]}
/>
-The Linear MCP Sever offers a streamlined set of tools for interacting with Linear's issue tracking and team management features. With this MCP Sever, users can:
+The Linear MCP Server provides a comprehensive set of tools for interacting with Linear's issue tracking, project management, and team collaboration features. With this MCP Server, you can:
-- Retrieve detailed information about a specific issue, including their status, comments, and related dependencies.
-- Access comprehensive team information, including team members, roles, and settings.
+- **Issues**: Create, update, search, and manage issues with full support for labels, priorities, assignments, and workflow states
+- **Projects**: Create and manage projects, track milestones, and post status updates
+- **Initiatives**: Manage high-level strategic goals and link projects to initiatives
+- **Teams**: Access team information and member details
+- **Cycles**: Work with time-boxed iterations (sprints) for organizing work
+- **Comments**: Add, update, and reply to comments on issues
+- **GitHub Integration**: Link GitHub PRs, commits, and issues to Linear issues
+- **User Context**: Access notifications, recent activity, and authenticated user information
-This MCP Sever is ideal for users looking to read and analyze issue and team data within Linear without making any modifications.
-
-## Available Tools
+## Available tools
@@ -45,13 +101,280 @@ This MCP Sever is ideal for users looking to read and analyze issue and team dat
tools](/home/build-tools/create-a-mcp-server).
-## Linear.GetIssue
+
+Each tool includes behavior hints as defined by the [Model Context Protocol](https://modelcontextprotocol.io/specification/2025-06-18/server/tools#tool) specification. These hints are not yet supported, but we've added them to help you understand the side effects of each tool:
+
+- `readOnlyHint` — The tool only reads data, no modifications
+- `openWorldHint` — The tool interacts with external systems (Linear's API)
+- `destructiveHint` — The tool may cause irreversible changes (e.g., deletion)
+- `idempotentHint` — Repeated calls with the same arguments have no additional effect
+
+
+---
+
+## User context tools
+
+### Linear.WhoAmI
+
+Get the authenticated user's profile and team memberships.
+
+
+
+
+Returns the current user's information including their name, email, organization, and the teams they belong to.
+
+**Parameters**
+
+This tool takes no parameters.
+
+
+- `readOnlyHint: true` - Only reads user profile, no modifications
+- `openWorldHint: true` - Interacts with Linear's external API
+
+
+
+Makes 2 API calls (viewer + viewer_teams) executed in parallel.
+
+
+---
+
+### Linear.GetNotifications
+
+Get the authenticated user's notifications.
+
+
+
+
+Returns notifications including issue mentions, comments, assignments, and state changes.
+
+**Parameters**
+
+- **unread_only** (`boolean`, _optional_) Only return unread notifications. Default is `False`.
+- **limit** (`integer`, _optional_) Maximum number of notifications to return. Min 1, max 50. Default is 20.
+- **end_cursor** (`string`, _optional_) Cursor for pagination. Use 'end_cursor' from previous response. Default is None.
+
+
+- `readOnlyHint: true` - Only reads notifications, no modifications
+- `openWorldHint: true` - Interacts with Linear's external API
+
+
+
+Makes 1 API call.
+
+
+---
+
+### Linear.GetRecentActivity
+
+Get the authenticated user's recent issue activity.
+
+
+
+
+Returns issues the user has recently created or been assigned to within the specified time period.
+
+**Parameters**
+
+- **days** (`integer`, _optional_) Number of days to look back for activity. Min 1, max 90. Default is 30.
+- **limit** (`integer`, _optional_) Maximum number of activities to return. Min 1, max 50. Default is 20.
+
+
+- `readOnlyHint: true` - Only reads activity data, no modifications
+- `openWorldHint: true` - Interacts with Linear's external API
+
+
+
+Makes 3 API calls (viewer + created issues + assigned issues) with issues
+ fetched in parallel.
+
+
+---
+
+## Team tools
+
+### Linear.GetTeam
+
+Get detailed information about a specific Linear team.
+
+
+
+
+Supports lookup by ID, key (like TOO, ENG), or name (with fuzzy matching).
+
+**Parameters**
+
+- **value** (`string`, **required**) The value to look up (ID, key, or name depending on lookup_by).
+- **lookup_by** (`enum`, _optional_) How to look up the team. Options: `id`, `key`, `name`. Default is `id`.
+- **auto_accept_matches** (`boolean`, _optional_) Auto-accept fuzzy matches above 90% confidence. Only used when lookup_by is name. Default is `False`.
+
+
+- `readOnlyHint: true` - Only reads team data, no modifications
+- `openWorldHint: true` - Interacts with Linear's external API
+
+
+
+Makes 1-2 API calls (ID: 1 call, KEY: 1 call, NAME: 1-2 calls if fuzzy match
+ auto-accepts).
+
+
+---
+
+### Linear.ListTeams
+
+List Linear teams, optionally filtered by keywords and other criteria.
+
+
+
+
+Returns all teams when no filters provided, or filtered results when keywords or other filters are specified.
+
+**Parameters**
+
+- **keywords** (`string`, _optional_) Search keywords to match in team names. Default is None (all teams).
+- **include_archived** (`boolean`, _optional_) Include archived teams in results. Default is `False`.
+- **created_after** (`string`, _optional_) Filter teams created after this date in ISO format (YYYY-MM-DD). Default is None (all time).
+- **limit** (`integer`, _optional_) Maximum number of teams to return. Min 1, max 50. Default is 20.
+- **end_cursor** (`string`, _optional_) Cursor for pagination. Use 'end_cursor' from previous response. Default is None.
+
+
+- `readOnlyHint: true` - Only reads team data, no modifications
+- `openWorldHint: true` - Interacts with Linear's external API
+
+
+
+Makes 1 API call.
+
+
+---
+
+## Issue tools
+
+### Linear.ListIssues
+
+List Linear issues, optionally filtered by keywords and other criteria.
+
+
+
+
+Returns all issues when no filters provided, or filtered results when keywords or other filters are specified.
+
+**Parameters**
+
+- **keywords** (`string`, _optional_) Search keywords to match in issue titles and descriptions. Default is None.
+- **team** (`string`, _optional_) Filter by team name or key. Default is None (all teams).
+- **state** (`string`, _optional_) Filter by workflow state name. Default is None (all states).
+- **assignee** (`string`, _optional_) Filter by assignee. Use '@me' for current user. Default is None.
+- **priority** (`enum`, _optional_) Filter by priority level. Options: `urgent`, `high`, `medium`, `low`, `no_priority`. Default is None.
+- **label** (`string`, _optional_) Filter by label name. Default is None.
+- **project** (`string`, _optional_) Filter by project name. Default is None.
+- **created_after** (`string`, _optional_) Filter issues created after this date in ISO format (YYYY-MM-DD). Default is None.
+- **limit** (`integer`, _optional_) Maximum number of issues to return. Min 1, max 50. Default is 20.
+- **end_cursor** (`string`, _optional_) Cursor for pagination. Use 'end_cursor' from previous response. Default is None.
+
+
+- `readOnlyHint: true` - Only reads issue data, no modifications
+- `openWorldHint: true` - Interacts with Linear's external API
+
+
+
+Makes 1 API call.
+
+
+---
+
+### Linear.GetIssue
+
+Get detailed information about a specific Linear issue.
-Get detailed information about a specific Linear issue
+Accepts either the issue UUID or the human-readable identifier (like TOO-123).
+
+**Parameters**
+
+- **issue_id** (`string`, **required**) The Linear issue ID or identifier (like TOO-123).
+- **include_comments** (`boolean`, _optional_) Include comments in the response. Default is `True`.
+- **include_attachments** (`boolean`, _optional_) Include attachments in the response. Default is `True`.
+- **include_relations** (`boolean`, _optional_) Include issue relations (blocks, dependencies). Default is `True`.
+- **include_children** (`boolean`, _optional_) Include sub-issues in the response. Default is `True`.
+
+
+- `readOnlyHint: true` - Only reads issue data, no modifications
+- `openWorldHint: true` - Interacts with Linear's external API
+
+
+
+Makes 1 API call.
+
+
+---
+
+### Linear.CreateIssue
+
+Create a new Linear issue with validation.
+
+
+
+
+All entity references (team, assignee, labels, state, project, cycle, parent) are validated before creation. If an entity is not found, suggestions are returned to help correct the input.
+
+**Parameters**
+
+- **team** (`string`, **required**) Team name, key, or ID.
+- **title** (`string`, **required**) Issue title.
+- **description** (`string`, _optional_) Issue description in Markdown format. Default is None.
+- **assignee** (`string`, _optional_) Assignee name or email. Use '@me' for current user. Must be a team member. Default is '@me'.
+- **labels_to_add** (`array`, _optional_) Labels to add by name or ID. Default is None.
+- **priority** (`enum`, _optional_) Issue priority. Options: `urgent`, `high`, `medium`, `low`, `no_priority`. Default is None.
+- **state** (`string`, _optional_) Initial workflow state name. Default is team's default state.
+- **project** (`string`, _optional_) Project name, slug, or ID to link. Default is None.
+- **cycle** (`string`, _optional_) Cycle name or number to link. Default is None.
+- **parent_issue** (`string`, _optional_) Parent issue identifier to make this a sub-issue. Default is None.
+- **estimate** (`integer`, _optional_) Effort estimate in points. Default is None.
+- **due_date** (`string`, _optional_) Due date in YYYY-MM-DD format. Default is None.
+- **attachment_url** (`string`, _optional_) URL to attach to the issue. Default is None.
+- **attachment_title** (`string`, _optional_) Title for the attached URL. Default is None (URL used as title).
+- **auto_accept_matches** (`boolean`, _optional_) Auto-accept fuzzy matches above 90% confidence. Default is `False`.
+
+
+- `readOnlyHint: false` - Creates new issue in Linear
+- `destructiveHint:
+ false` - Additive operation, creates new resource
+- `idempotentHint: false` -
+ Each call creates a new issue
+- `openWorldHint: true` - Interacts with
+ Linear's external API
+
+
+
+Makes 2-5 API calls (validation + create, +1 if @me assignee, +1 if
+ parent_issue, +1 if attachment).
+
+
+---
+
+### Linear.UpdateIssue
+
+Update a Linear issue with partial updates.
+
+
+
+
+Only fields that are explicitly provided will be updated. All entity references are validated before update.
+
+**Parameters**
+
+- **issue_id** (`string`, **required**) Issue ID or identifier (like TOO-123).
+- **title** (`string`, _optional_) New issue title. Only updated if provided.
+- **description** (`string`, _optional_) New description in Markdown. Only updated if provided.
+- **assignee** (`string`, _optional_) New assignee name or email. Use '@me' for current user. Only updated if provided.
+- **labels_to_add** (`array`, _optional_) Labels to add by name or ID. Default is None.
+- **labels_to_remove** (`array`, _optional_) Labels to remove by name or ID. Default is None.
+- **priority** (`enum`, _optional_) New priority. Options: `urgent`, `high`, `medium`, `low`, `no_priority`. Only updated if provided.
+- **state** (`string`, _optional_) New workflow state name. Only updated if provided.
+- **project** (`string`, _optional_) Project to link (name, slug, or ID). Only updated if provided.
+- **cycle** (`string`, _optional_) Cycle to link (name or number). Only updated if provided.
+- **estimate** (`integer`, _optional_) New effort estimate in points. Only updated if provided.
+- **due_date** (`string`, _optional_) New due date in YYYY-MM-DD format. Only updated if provided.
+- **attachment_url** (`string`, _optional_) URL to attach to the issue. Default is None.
+- **attachment_title** (`string`, _optional_) Title for the attached URL. Default is None (URL used as title).
+- **auto_accept_matches** (`boolean`, _optional_) Auto-accept fuzzy matches above 90% confidence. Default is `False`.
+
+
+- `readOnlyHint: false` - Modifies existing issue
+- `destructiveHint: false` -
+ Updates fields, doesn't delete
+- `idempotentHint: true` - Same update with
+ same args = same result
+- `openWorldHint: true` - Interacts with Linear's
+ external API
+
+
+
+Makes 2-5 API calls (issue lookup + validation, +1 if @me, +1 for update, +1
+ if attachment).
+
+
+---
+
+### Linear.TransitionIssueState
+
+Transition a Linear issue to a new workflow state.
+
+
+
+
+The target state is validated against the team's available states.
**Parameters**
-- **issue_id** (`string`, required) The Linear issue ID or identifier (e.g. 'FE-123', 'API-456') to retrieve.
-- **include_comments** (`boolean`, optional) Whether to include comments in the response. Defaults to True.
-- **include_attachments** (`boolean`, optional) Whether to include attachments in the response. Defaults to True.
-- **include_relations** (`boolean`, optional) Whether to include issue relations (blocks, dependencies) in the response. Defaults to True.
-- **include_children** (`boolean`, optional) Whether to include sub-issues in the response. Defaults to True.
+- **issue_id** (`string`, **required**) Issue ID or identifier (like TOO-123).
+- **target_state** (`string`, **required**) Target workflow state name.
+- **auto_accept_matches** (`boolean`, _optional_) Auto-accept fuzzy matches above 90% confidence. Default is `False`.
+
+
+- `readOnlyHint: false` - Changes issue workflow state
+- `destructiveHint:
+ false` - Updates state, doesn't delete
+- `idempotentHint: true` -
+ Transitioning to same state = no change
+- `openWorldHint: true` - Interacts
+ with Linear's external API
+
+
+
+Makes 2-3 API calls (1 for issue lookup, 1 for validation data, 1 for update).
+
+
+---
+
+### Linear.CreateIssueRelation
-## Linear.GetTeams
+Create a relation between two issues.
-Get Linear teams and team information including team members
+Relation types define the relationship from the source issue's perspective:
+
+- `blocks`: Source issue blocks the related issue
+- `blockedBy`: Source issue is blocked by the related issue
+- `duplicate`: Source issue is a duplicate of the related issue
+- `related`: Issues are related (bidirectional)
**Parameters**
-- **team_name** (`string`, optional) Filter by team name. Provide specific team name (e.g. 'Frontend', 'Product Web') or partial name. Use this to find specific teams or check team membership. Defaults to None (all teams).
-- **include_archived** (`boolean`, optional) Whether to include archived teams in results. Defaults to False.
-- **created_after** (`string`, optional) Filter teams created after this date. Can be:
-- Relative date string (e.g. 'last month', 'this week', 'yesterday')
-- ISO date string (e.g. 'YYYY-MM-DD')
- Defaults to None (all time).
-- **limit** (`integer`, optional) Maximum number of teams to return. Min 1, max 100. Defaults to 50.
-- **end_cursor** (`string`, optional) Cursor for pagination - get teams after this cursor. Use the 'end_cursor' from previous response. Defaults to None (start from beginning).
+- **issue** (`string`, **required**) Source issue ID or identifier.
+- **related_issue** (`string`, **required**) Related issue ID or identifier.
+- **relation_type** (`enum`, **required**) Type of relation to create. Options: `blocks`, `blockedBy`, `duplicate`, `related`.
+
+
+- `readOnlyHint: false` - Creates relation between issues
+- `destructiveHint:
+ false` - Additive operation, creates link
+- `idempotentHint: true` - Creating
+ same relation again = no change
+- `openWorldHint: true` - Interacts with
+ Linear's external API
+
+
+
+Makes 3 API calls (get source + related issue in parallel, create relation).
+
+
+---
+
+### Linear.ManageIssueSubscription
+
+Subscribe to or unsubscribe from an issue's notifications.
+
+
+
+
+**Parameters**
+
+- **issue** (`string`, **required**) Issue ID or identifier.
+- **subscribe** (`boolean`, **required**) True to subscribe, False to unsubscribe.
+
+
+- `readOnlyHint: false` - Modifies user's subscription state -
+- `destructiveHint: false` - Toggles subscription, reversible
+- `idempotentHint:
+ true` - Subscribing when subscribed = no change
+- `openWorldHint: true` -
+ Interacts with Linear's external API
+
+
+
+Makes 2 API calls (get issue, subscribe/unsubscribe).
+
+
+---
+
+### Linear.ArchiveIssue
+
+Archive an issue.
+
+
+
+
+Archived issues are hidden from default views but can be restored.
+
+**Parameters**
+
+- **issue** (`string`, **required**) Issue ID or identifier to archive.
+
+
+- `readOnlyHint: false` - Archives (soft-deletes) issue
+- `destructiveHint:
+ true` - Hides issue from default views
+- `idempotentHint: true` - Archiving
+ already-archived = no change
+- `openWorldHint: true` - Interacts with Linear's
+ external API
+
+
+
+Makes 2 API calls (get issue, archive).
+
+
+---
+
+## Comment tools
+
+### Linear.ListComments
+
+List comments on an issue.
+
+
+
+
+Returns comments with user info, timestamps, and reply threading info.
+
+**Parameters**
+
+- **issue** (`string`, **required**) Issue ID or identifier.
+- **limit** (`integer`, _optional_) Maximum number of comments to return. Min 1, max 50. Default is 20.
+- **end_cursor** (`string`, _optional_) Cursor for pagination. Use 'end_cursor' from previous response. Default is None.
+
+
+- `readOnlyHint: true` - Only reads comment data, no modifications
+- `openWorldHint: true` - Interacts with Linear's external API
+
+
+
+Makes 2 API calls (get issue, get comments).
+
+
+---
+
+### Linear.AddComment
+
+Add a comment to an issue.
+
+
+
+
+**Parameters**
+
+- **issue** (`string`, **required**) Issue ID or identifier to comment on.
+- **body** (`string`, **required**) Comment body in Markdown format.
+
+
+- `readOnlyHint: false` - Creates new comment on issue
+- `destructiveHint:
+ false` - Additive operation, creates new comment
+- `idempotentHint: false` -
+ Each call creates a new comment
+- `openWorldHint: true` - Interacts with
+ Linear's external API
+
+
+
+Makes 2 API calls (get issue, create comment).
+
+
+---
+
+### Linear.UpdateComment
+
+Update an existing comment.
+
+
+
+
+**Parameters**
+
+- **comment_id** (`string`, **required**) Comment ID to update.
+- **body** (`string`, **required**) New comment body in Markdown format.
+
+
+- `readOnlyHint: false` - Modifies existing comment
+- `destructiveHint: false`
+- Updates content, doesn't delete
+- `idempotentHint: true` - Same update with
+ same args = same result
+- `openWorldHint: true` - Interacts with Linear's
+ external API
+
+
+
+Makes 1 API call.
+
+
+---
+
+### Linear.ReplyToComment
+
+Reply to an existing comment on an issue.
+
+
+
+
+Creates a threaded reply to the specified parent comment.
+
+**Parameters**
+
+- **issue** (`string`, **required**) Issue ID or identifier.
+- **parent_comment_id** (`string`, **required**) ID of the comment to reply to.
+- **body** (`string`, **required**) Reply body in Markdown format.
+
+
+- `readOnlyHint: false` - Creates reply to existing comment -
+- `destructiveHint: false` - Additive operation, creates new reply -
+- `idempotentHint: false` - Each call creates a new reply
+- `openWorldHint:
+ true` - Interacts with Linear's external API
+
+
+
+Makes 2 API calls (get issue, create reply).
+
+
+---
+
+## Project tools
+
+### Linear.GetProject
+
+Get detailed information about a specific Linear project.
+
+
+
+
+Supports lookup by ID, slug_id, or name (with fuzzy matching for name).
+
+**Parameters**
+
+- **value** (`string`, **required**) The value to look up (ID, slug_id, or name depending on lookup_by).
+- **lookup_by** (`enum`, _optional_) How to look up the project. Options: `id`, `slug_id`, `name`. Default is `id`.
+- **include_milestones** (`boolean`, _optional_) Include project milestones in the response. Default is `True`.
+- **include_members** (`boolean`, _optional_) Include project members in the response. Default is `True`.
+- **include_issues** (`boolean`, _optional_) Include latest 10 issues (by updated_at) in the response. Default is `True`.
+- **auto_accept_matches** (`boolean`, _optional_) Auto-accept fuzzy matches above 90% confidence. Only used when lookup_by is name. Default is `False`.
+
+
+- `readOnlyHint: true` - Only reads project data, no modifications
+- `openWorldHint: true` - Interacts with Linear's external API
+
+
+
+Makes 1-2 API calls (1 for ID/slug lookup, 2 if fuzzy matching by name).
+
+
+---
+
+### Linear.ListProjects
+
+List Linear projects, optionally filtered by keywords and other criteria.
+
+
+
+
+Returns all projects when no filters provided, or filtered results when keywords or other filters are specified.
+
+**Parameters**
+
+- **keywords** (`string`, _optional_) Search keywords to match in project names. Default is None (all projects).
+- **state** (`string`, _optional_) Filter by project state. Default is None (all states).
+- **team** (`string`, _optional_) Filter by team name. Default is None (all teams).
+- **created_after** (`string`, _optional_) Filter projects created after this date in ISO format (YYYY-MM-DD). Default is None (all time).
+- **limit** (`integer`, _optional_) Maximum number of projects to return. Min 1, max 50. Default is 20.
+- **end_cursor** (`string`, _optional_) Cursor for pagination. Use 'end_cursor' from previous response. Default is None.
+
+
+- `readOnlyHint: true` - Only reads project data, no modifications
+- `openWorldHint: true` - Interacts with Linear's external API
+
+
+
+Makes 1 API call.
+
+
+---
+
+### Linear.GetProjectDescription
+
+Get a project's full description with pagination support.
+
+
+
+
+Use this tool when you need the complete description of a project that was truncated in the get_project response. Supports chunked reading for very large descriptions.
+
+**Parameters**
+
+- **project_id** (`string`, **required**) The project ID or slug_id.
+- **offset** (`integer`, _optional_) Character offset to start reading from. Default is 0 (start).
+- **limit** (`integer`, _optional_) Maximum characters to return. Default is 5000.
+
+
+- `readOnlyHint: true` - Only reads description, no modifications
+- `openWorldHint: true` - Interacts with Linear's external API
+
+
+
+Makes 1 API call.
+
+
+---
+
+### Linear.CreateProject
+
+Create a new Linear project.
+
+
+
+
+Team is validated before creation. If team is not found, suggestions are returned to help correct the input. Lead is validated if provided.
+
+**Parameters**
+
+- **name** (`string`, **required**) Project name.
+- **team** (`string`, **required**) Team name, key, or ID to associate the project with.
+- **description** (`string`, _optional_) Project description in Markdown format. Default is None.
+- **state** (`enum`, _optional_) Initial project state. Options: `planned`, `started`, `paused`, `completed`, `canceled`. Default is None (uses Linear default).
+- **lead** (`string`, _optional_) Project lead name or email. Must be a workspace member. Default is None.
+- **start_date** (`string`, _optional_) Project start date in YYYY-MM-DD format. Default is None.
+- **target_date** (`string`, _optional_) Target completion date in YYYY-MM-DD format. Default is None.
+- **auto_accept_matches** (`boolean`, _optional_) Auto-accept fuzzy matches above 90% confidence. Default is `False`.
+
+
+- `readOnlyHint: false` - Creates new project in Linear
+- `destructiveHint:
+ false` - Additive operation, creates new resource
+- `idempotentHint: false` -
+ Each call creates a new project
+- `openWorldHint: true` - Interacts with
+ Linear's external API
+
+
+
+Makes 2 API calls (1 for validation data, 1 for creation).
+
+
+---
+
+### Linear.UpdateProject
+
+Update a Linear project with partial updates.
+
+
+
+
+Only fields that are explicitly provided will be updated. All entity references are validated before update.
+
+**Parameters**
+
+- **project_id** (`string`, **required**) Project ID or slug_id.
+- **name** (`string`, _optional_) New project name. Only updated if provided.
+- **description** (`string`, _optional_) New project description in Markdown format. Only updated if provided.
+- **state** (`enum`, _optional_) New project state. Options: `planned`, `started`, `paused`, `completed`, `canceled`. Only updated if provided.
+- **lead** (`string`, _optional_) New project lead name or email. Only updated if provided.
+- **start_date** (`string`, _optional_) New start date in YYYY-MM-DD format. Only updated if provided.
+- **target_date** (`string`, _optional_) New target date in YYYY-MM-DD format. Only updated if provided.
+- **teams_to_add** (`array`, _optional_) Team names, keys, or IDs to add to the project. Only updated if provided.
+- **teams_to_remove** (`array`, _optional_) Team names, keys, or IDs to remove from the project. Only updated if provided.
+- **auto_accept_matches** (`boolean`, _optional_) Auto-accept fuzzy matches above 90% confidence. Default is `False`.
+
+
+- `readOnlyHint: false` - Modifies existing project
+- `destructiveHint: false`
+- Updates fields, doesn't delete
+- `idempotentHint: true` - Same update with
+ same args = same result
+- `openWorldHint: true` - Interacts with Linear's
+ external API
+
+
+
+Makes 1-3 API calls (1 for update, +1-2 if resolving lead/team).
+
+
+---
+
+### Linear.CreateProjectUpdate
+
+Create a project status update.
+
+
+
+
+Project updates are posts that communicate progress, blockers, or status changes to stakeholders. They appear in the project's Updates tab and can include a health status indicator.
+
+**Parameters**
+
+- **project_id** (`string`, **required**) The project ID to create an update for.
+- **body** (`string`, **required**) The update content in Markdown format.
+- **health** (`enum`, _optional_) Project health status. Options: `onTrack`, `atRisk`, `offTrack`. Default is None (no change).
+
+
+- `readOnlyHint: false` - Creates status update post
+- `destructiveHint:
+ false` - Additive operation, creates new update
+- `idempotentHint: false` -
+ Each call creates a new update
+- `openWorldHint: true` - Interacts with
+ Linear's external API
+
+
+
+Makes 1 API call.
+
+
+---
+
+### Linear.ArchiveProject
+
+Archive a project.
+
+
+
+
+Archived projects are hidden from default views but can be restored.
+
+**Parameters**
+
+- **project** (`string`, **required**) Project ID, slug_id, or name to archive.
+- **auto_accept_matches** (`boolean`, _optional_) Auto-accept fuzzy matches above 90% confidence. Default is `False`.
+
+
+- `readOnlyHint: false` - Archives (soft-deletes) project
+- `destructiveHint:
+ true` - Hides project from default views
+- `idempotentHint: true` - Archiving
+ already-archived = no change
+- `openWorldHint: true` - Interacts with Linear's
+ external API
+
+
+
+Makes 2 API calls (get project, archive).
+
+
+---
+
+## Initiative tools
+
+### Linear.GetInitiative
+
+Get detailed information about a specific Linear initiative.
+
+
+
+
+Supports lookup by ID or name (with fuzzy matching for name).
+
+**Parameters**
+
+- **value** (`string`, **required**) The value to look up (ID or name depending on lookup_by).
+- **lookup_by** (`enum`, _optional_) How to look up the initiative. Options: `id`, `name`. Default is `id`.
+- **include_projects** (`boolean`, _optional_) Include linked projects in the response. Default is `True`.
+- **auto_accept_matches** (`boolean`, _optional_) Auto-accept fuzzy matches above 90% confidence. Only used when lookup_by is name. Default is `False`.
+
+
+- `readOnlyHint: true` - Only reads initiative data, no modifications
+- `openWorldHint: true` - Interacts with Linear's external API
+
+
+
+Makes 1-2 API calls (1 for ID lookup, 2 if fuzzy matching by name).
+
+
+---
+
+### Linear.ListInitiatives
+
+List Linear initiatives, optionally filtered by keywords and other criteria.
+
+
+
+
+Returns all initiatives when no filters provided, or filtered results when keywords or other filters are specified.
+
+**Parameters**
+
+- **keywords** (`string`, _optional_) Search keywords to match in initiative names. Default is None (all initiatives).
+- **state** (`enum`, _optional_) Filter by initiative state. Options: `planned`, `started`, `paused`, `completed`. Default is None (all states).
+- **limit** (`integer`, _optional_) Maximum number of initiatives to return. Min 1, max 50. Default is 20.
+- **end_cursor** (`string`, _optional_) Cursor for pagination. Use 'end_cursor' from previous response. Default is None.
+
+
+- `readOnlyHint: true` - Only reads initiative data, no modifications
+- `openWorldHint: true` - Interacts with Linear's external API
+
+
+
+Makes 1 API call.
+
+
+---
+
+### Linear.GetInitiativeDescription
+
+Get an initiative's full description with pagination support.
+
+
+
+
+Use this tool when you need the complete description of an initiative that was truncated in the get_initiative response. Supports chunked reading for very large descriptions.
+
+**Parameters**
+
+- **initiative_id** (`string`, **required**) The initiative ID.
+- **offset** (`integer`, _optional_) Character offset to start reading from. Default is 0 (start).
+- **limit** (`integer`, _optional_) Maximum characters to return. Default is 5000.
+
+
+- `readOnlyHint: true` - Only reads description, no modifications
+- `openWorldHint: true` - Interacts with Linear's external API
+
+
+
+Makes 1 API call.
+
+
+---
+
+### Linear.CreateInitiative
+
+Create a new Linear initiative.
+
+
+
+
+Initiatives are high-level strategic goals that group related projects.
+
+**Parameters**
+
+- **name** (`string`, **required**) Initiative name.
+- **description** (`string`, _optional_) Initiative description in Markdown format. Default is None.
+- **status** (`enum`, _optional_) Initial initiative status. Options: `planned`, `started`, `paused`, `completed`. Default is None (uses Linear default).
+- **target_date** (`string`, _optional_) Target completion date in YYYY-MM-DD format. Default is None.
+
+
+- `readOnlyHint: false` - Creates new initiative in Linear
+- `destructiveHint:
+ false` - Additive operation, creates new resource
+- `idempotentHint: false` -
+ Each call creates a new initiative
+- `openWorldHint: true` - Interacts with
+ Linear's external API
+
+
+
+Makes 1 API call.
+
+
+---
+
+### Linear.UpdateInitiative
+
+Update a Linear initiative with partial updates.
+
+
+
+
+Only fields that are explicitly provided will be updated.
+
+**Parameters**
+
+- **initiative_id** (`string`, **required**) Initiative ID.
+- **name** (`string`, _optional_) New initiative name. Only updated if provided.
+- **description** (`string`, _optional_) New initiative description in Markdown format. Only updated if provided.
+- **status** (`enum`, _optional_) New initiative status. Options: `planned`, `started`, `paused`, `completed`. Only updated if provided.
+- **target_date** (`string`, _optional_) New target date in YYYY-MM-DD format. Only updated if provided.
+
+
+- `readOnlyHint: false` - Modifies existing initiative
+- `destructiveHint:
+ false` - Updates fields, doesn't delete
+- `idempotentHint: true` - Same update
+ with same args = same result
+- `openWorldHint: true` - Interacts with Linear's
+ external API
+
+
+
+Makes 1 API call.
+
+
+---
+
+### Linear.AddProjectToInitiative
+
+Link a project to an initiative.
+
+
+
+
+Both initiative and project can be specified by ID or name. If a name is provided, fuzzy matching is used to resolve it.
+
+**Parameters**
+
+- **initiative** (`string`, **required**) Initiative ID or name to link the project to.
+- **project** (`string`, **required**) Project ID or name to link.
+- **auto_accept_matches** (`boolean`, _optional_) Auto-accept fuzzy matches above 90% confidence. Default is `False`.
+
+
+- `readOnlyHint: false` - Creates link between project and initiative -
+- `destructiveHint: false` - Additive operation, creates association -
+- `idempotentHint: true` - Linking same project again = no change -
+- `openWorldHint: true` - Interacts with Linear's external API
+
+
+
+Makes 3 API calls (initiatives query, projects query,
+ initiativeToProjectCreate mutation).
+
+
+---
+
+### Linear.ArchiveInitiative
+
+Archive an initiative.
+
+
+
+
+Archived initiatives are hidden from default views but can be restored.
+
+**Parameters**
+
+- **initiative** (`string`, **required**) Initiative ID or name to archive.
+- **auto_accept_matches** (`boolean`, _optional_) Auto-accept fuzzy matches above 90% confidence. Default is `False`.
+
+
+- `readOnlyHint: false` - Archives (soft-deletes) initiative -
+- `destructiveHint: true` - Hides initiative from default views -
+- `idempotentHint: true` - Archiving already-archived = no change -
+- `openWorldHint: true` - Interacts with Linear's external API
+
+
+
+Makes 2 API calls (get initiative, archive).
+
+
+---
+
+## Cycle tools
+
+### Linear.GetCycle
+
+Get detailed information about a specific Linear cycle.
+
+
+
+
+**Parameters**
+
+- **cycle_id** (`string`, **required**) The cycle ID.
+
+
+- `readOnlyHint: true` - Only reads cycle data, no modifications
+- `openWorldHint: true` - Interacts with Linear's external API
+
+
+
+Makes 1 API call.
+
+
+---
+
+### Linear.ListCycles
+
+List Linear cycles, optionally filtered by team and status.
+
+
+
+
+Cycles are time-boxed iterations (like sprints) for organizing work.
+
+**Parameters**
+
+- **team** (`string`, _optional_) Filter by team ID or key. Default is None (all teams).
+- **active_only** (`boolean`, _optional_) Only return currently active cycles. Default is `False`.
+- **include_completed** (`boolean`, _optional_) Include completed cycles. Default is `True`.
+- **limit** (`integer`, _optional_) Maximum number of cycles to return. Min 1, max 50. Default is 20.
+- **end_cursor** (`string`, _optional_) Cursor for pagination. Use 'end_cursor' from previous response. Default is None.
+
+
+- `readOnlyHint: true` - Only reads cycle data, no modifications
+- `openWorldHint: true` - Interacts with Linear's external API
+
+
+
+Makes 1-2 API calls (1 for cycles, +1 if team filter provided to resolve team
+ ID).
+
+
+---
+
+## Metadata tools
+
+### Linear.ListLabels
+
+List available issue labels in the workspace.
+
+
+
+
+Returns labels that can be applied to issues. Use label IDs or names when creating or updating issues.
+
+**Parameters**
+
+- **limit** (`integer`, _optional_) Maximum number of labels to return. Min 1, max 100. Default is 50.
+
+
+- `readOnlyHint: true` - Only reads label data, no modifications
+- `openWorldHint: true` - Interacts with Linear's external API
+
+
+
+Makes 1 API call.
+
+
+---
+
+### Linear.ListWorkflowStates
+
+List available workflow states in the workspace.
+
+
+
+
+Returns workflow states that can be used for issue transitions. States are team-specific and have different types.
+
+**Parameters**
+
+- **team** (`string`, _optional_) Filter by team name or key. Default is None (all teams).
+- **state_type** (`enum`, _optional_) Filter by state type. Options: `triage`, `backlog`, `unstarted`, `started`, `completed`, `canceled`. Default is None (all types).
+- **limit** (`integer`, _optional_) Maximum number of states to return. Min 1, max 100. Default is 50.
+
+
+- `readOnlyHint: true` - Only reads workflow state data, no modifications
+- `openWorldHint: true` - Interacts with Linear's external API
+
+
+
+Makes 1 API call.
+
+
+---
+
+## GitHub integration tools
+
+### Linear.LinkGithubToIssue
+
+Link a GitHub PR, commit, or issue to a Linear issue.
+
+
+
+
+Automatically detects the artifact type from the URL and generates an appropriate title if not provided.
+
+**Parameters**
+
+- **issue** (`string`, **required**) Issue ID or identifier to link to.
+- **github_url** (`string`, **required**) GitHub URL to link (PR, commit, or issue).
+- **title** (`string`, _optional_) Custom title for the link. If not provided, auto-generated from URL.
+
+
+- `readOnlyHint: false` - Attaches GitHub link to issue
+- `destructiveHint:
+ false` - Additive operation, creates attachment
+- `idempotentHint: true` -
+ Linking same URL again = no change
+- `openWorldHint: true` - Interacts with
+ Linear's external API
+
+
+
+Makes 2 API calls (get issue, link URL).
+
+
+---
## Auth
-The Arcade Linear MCP Sever uses the [Linear auth provider](/home/auth-providers/linear) to connect to users' Linear accounts. Please refer to the [Linear auth provider](/home/auth-providers/linear) documentation to learn how to configure auth.
+The Arcade Linear MCP Server uses the [Linear auth provider](/home/auth-providers/linear) to connect to users' Linear accounts. Please refer to the [Linear auth provider](/home/auth-providers/linear) documentation to learn how to configure auth.
diff --git a/next-env.d.ts b/next-env.d.ts
index 0c7fad710..c4b7818fb 100644
--- a/next-env.d.ts
+++ b/next-env.d.ts
@@ -1,6 +1,5 @@
///
///
-///
import "./.next/dev/types/routes.d.ts";
// NOTE: This file should not be edited
diff --git a/public/examples/integrations/mcp-servers/linear/add_comment_example_call_tool.js b/public/examples/integrations/mcp-servers/linear/add_comment_example_call_tool.js
new file mode 100644
index 000000000..0c3acb56a
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/add_comment_example_call_tool.js
@@ -0,0 +1,30 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
+
+const USER_ID = "{arcade_user_id}"; // Unique identifier for your user (email, UUID, etc.)
+const TOOL_NAME = "Linear.AddComment";
+
+// Start the authorization process
+const authResponse = await client.tools.authorize({tool_name: TOOL_NAME, user_id: USER_ID});
+
+if (authResponse.status !== "completed") {
+ console.log(`Click this link to authorize: ${authResponse.url}`);
+}
+
+// Wait for the authorization to complete
+await client.auth.waitForCompletion(authResponse);
+
+const toolInput = {
+ "issue": "PROJ-123",
+ "body": "This is a comment in **Markdown** format."
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
+
diff --git a/public/examples/integrations/mcp-servers/linear/add_comment_example_call_tool.py b/public/examples/integrations/mcp-servers/linear/add_comment_example_call_tool.py
new file mode 100644
index 000000000..66b605823
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/add_comment_example_call_tool.py
@@ -0,0 +1,28 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
+
+USER_ID = "{arcade_user_id}" # Unique identifier for your user (email, UUID, etc.)
+TOOL_NAME = "Linear.AddComment"
+
+auth_response = client.tools.authorize(tool_name=TOOL_NAME, user_id=USER_ID)
+
+if auth_response.status != "completed":
+ print(f"Click this link to authorize: {auth_response.url}")
+
+# Wait for the authorization to complete
+client.auth.wait_for_completion(auth_response)
+
+tool_input = {
+ "issue": "PROJ-123",
+ "body": "This is a comment in **Markdown** format."
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+)
+print(json.dumps(response.output.value, indent=2))
+
diff --git a/public/examples/integrations/mcp-servers/linear/add_project_to_initiative_example_call_tool.js b/public/examples/integrations/mcp-servers/linear/add_project_to_initiative_example_call_tool.js
new file mode 100644
index 000000000..92ef77778
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/add_project_to_initiative_example_call_tool.js
@@ -0,0 +1,31 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
+
+const USER_ID = "{arcade_user_id}"; // Unique identifier for your user (email, UUID, etc.)
+const TOOL_NAME = "Linear.AddProjectToInitiative";
+
+// Start the authorization process
+const authResponse = await client.tools.authorize({tool_name: TOOL_NAME, user_id: USER_ID});
+
+if (authResponse.status !== "completed") {
+ console.log(`Click this link to authorize: ${authResponse.url}`);
+}
+
+// Wait for the authorization to complete
+await client.auth.waitForCompletion(authResponse);
+
+const toolInput = {
+ "initiative": "Q4 Goals",
+ "project": "API Redesign",
+ "auto_accept_matches": true
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
+
diff --git a/public/examples/integrations/mcp-servers/linear/add_project_to_initiative_example_call_tool.py b/public/examples/integrations/mcp-servers/linear/add_project_to_initiative_example_call_tool.py
new file mode 100644
index 000000000..26268f9cc
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/add_project_to_initiative_example_call_tool.py
@@ -0,0 +1,29 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
+
+USER_ID = "{arcade_user_id}" # Unique identifier for your user (email, UUID, etc.)
+TOOL_NAME = "Linear.AddProjectToInitiative"
+
+auth_response = client.tools.authorize(tool_name=TOOL_NAME, user_id=USER_ID)
+
+if auth_response.status != "completed":
+ print(f"Click this link to authorize: {auth_response.url}")
+
+# Wait for the authorization to complete
+client.auth.wait_for_completion(auth_response)
+
+tool_input = {
+ "initiative": "Q4 Goals",
+ "project": "API Redesign",
+ "auto_accept_matches": True
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+)
+print(json.dumps(response.output.value, indent=2))
+
diff --git a/public/examples/integrations/mcp-servers/linear/archive_initiative_example_call_tool.js b/public/examples/integrations/mcp-servers/linear/archive_initiative_example_call_tool.js
new file mode 100644
index 000000000..be746651f
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/archive_initiative_example_call_tool.js
@@ -0,0 +1,30 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
+
+const USER_ID = "{arcade_user_id}"; // Unique identifier for your user (email, UUID, etc.)
+const TOOL_NAME = "Linear.ArchiveInitiative";
+
+// Start the authorization process
+const authResponse = await client.tools.authorize({tool_name: TOOL_NAME, user_id: USER_ID});
+
+if (authResponse.status !== "completed") {
+ console.log(`Click this link to authorize: ${authResponse.url}`);
+}
+
+// Wait for the authorization to complete
+await client.auth.waitForCompletion(authResponse);
+
+const toolInput = {
+ "initiative": "Old Q3 Goals",
+ "auto_accept_matches": true
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
+
diff --git a/public/examples/integrations/mcp-servers/linear/archive_initiative_example_call_tool.py b/public/examples/integrations/mcp-servers/linear/archive_initiative_example_call_tool.py
new file mode 100644
index 000000000..96face031
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/archive_initiative_example_call_tool.py
@@ -0,0 +1,28 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
+
+USER_ID = "{arcade_user_id}" # Unique identifier for your user (email, UUID, etc.)
+TOOL_NAME = "Linear.ArchiveInitiative"
+
+auth_response = client.tools.authorize(tool_name=TOOL_NAME, user_id=USER_ID)
+
+if auth_response.status != "completed":
+ print(f"Click this link to authorize: {auth_response.url}")
+
+# Wait for the authorization to complete
+client.auth.wait_for_completion(auth_response)
+
+tool_input = {
+ "initiative": "Old Q3 Goals",
+ "auto_accept_matches": True
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+)
+print(json.dumps(response.output.value, indent=2))
+
diff --git a/public/examples/integrations/mcp-servers/linear/archive_issue_example_call_tool.js b/public/examples/integrations/mcp-servers/linear/archive_issue_example_call_tool.js
new file mode 100644
index 000000000..b08ee5c74
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/archive_issue_example_call_tool.js
@@ -0,0 +1,29 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
+
+const USER_ID = "{arcade_user_id}"; // Unique identifier for your user (email, UUID, etc.)
+const TOOL_NAME = "Linear.ArchiveIssue";
+
+// Start the authorization process
+const authResponse = await client.tools.authorize({tool_name: TOOL_NAME, user_id: USER_ID});
+
+if (authResponse.status !== "completed") {
+ console.log(`Click this link to authorize: ${authResponse.url}`);
+}
+
+// Wait for the authorization to complete
+await client.auth.waitForCompletion(authResponse);
+
+const toolInput = {
+ "issue": "PROJ-123"
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
+
diff --git a/public/examples/integrations/mcp-servers/linear/archive_issue_example_call_tool.py b/public/examples/integrations/mcp-servers/linear/archive_issue_example_call_tool.py
new file mode 100644
index 000000000..503c7fd9a
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/archive_issue_example_call_tool.py
@@ -0,0 +1,27 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
+
+USER_ID = "{arcade_user_id}" # Unique identifier for your user (email, UUID, etc.)
+TOOL_NAME = "Linear.ArchiveIssue"
+
+auth_response = client.tools.authorize(tool_name=TOOL_NAME, user_id=USER_ID)
+
+if auth_response.status != "completed":
+ print(f"Click this link to authorize: {auth_response.url}")
+
+# Wait for the authorization to complete
+client.auth.wait_for_completion(auth_response)
+
+tool_input = {
+ "issue": "PROJ-123"
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+)
+print(json.dumps(response.output.value, indent=2))
+
diff --git a/public/examples/integrations/mcp-servers/linear/archive_project_example_call_tool.js b/public/examples/integrations/mcp-servers/linear/archive_project_example_call_tool.js
new file mode 100644
index 000000000..5f16215df
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/archive_project_example_call_tool.js
@@ -0,0 +1,30 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
+
+const USER_ID = "{arcade_user_id}"; // Unique identifier for your user (email, UUID, etc.)
+const TOOL_NAME = "Linear.ArchiveProject";
+
+// Start the authorization process
+const authResponse = await client.tools.authorize({tool_name: TOOL_NAME, user_id: USER_ID});
+
+if (authResponse.status !== "completed") {
+ console.log(`Click this link to authorize: ${authResponse.url}`);
+}
+
+// Wait for the authorization to complete
+await client.auth.waitForCompletion(authResponse);
+
+const toolInput = {
+ "project": "Old Project",
+ "auto_accept_matches": true
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
+
diff --git a/public/examples/integrations/mcp-servers/linear/archive_project_example_call_tool.py b/public/examples/integrations/mcp-servers/linear/archive_project_example_call_tool.py
new file mode 100644
index 000000000..7a718d8ed
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/archive_project_example_call_tool.py
@@ -0,0 +1,28 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
+
+USER_ID = "{arcade_user_id}" # Unique identifier for your user (email, UUID, etc.)
+TOOL_NAME = "Linear.ArchiveProject"
+
+auth_response = client.tools.authorize(tool_name=TOOL_NAME, user_id=USER_ID)
+
+if auth_response.status != "completed":
+ print(f"Click this link to authorize: {auth_response.url}")
+
+# Wait for the authorization to complete
+client.auth.wait_for_completion(auth_response)
+
+tool_input = {
+ "project": "Old Project",
+ "auto_accept_matches": True
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+)
+print(json.dumps(response.output.value, indent=2))
+
diff --git a/public/examples/integrations/mcp-servers/linear/create_initiative_example_call_tool.js b/public/examples/integrations/mcp-servers/linear/create_initiative_example_call_tool.js
new file mode 100644
index 000000000..ddfcd5317
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/create_initiative_example_call_tool.js
@@ -0,0 +1,32 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
+
+const USER_ID = "{arcade_user_id}"; // Unique identifier for your user (email, UUID, etc.)
+const TOOL_NAME = "Linear.CreateInitiative";
+
+// Start the authorization process
+const authResponse = await client.tools.authorize({tool_name: TOOL_NAME, user_id: USER_ID});
+
+if (authResponse.status !== "completed") {
+ console.log(`Click this link to authorize: ${authResponse.url}`);
+}
+
+// Wait for the authorization to complete
+await client.auth.waitForCompletion(authResponse);
+
+const toolInput = {
+ "name": "Q1 2025 Objectives",
+ "description": "Strategic goals for Q1 2025",
+ "status": "planned",
+ "target_date": "2025-03-31"
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
+
diff --git a/public/examples/integrations/mcp-servers/linear/create_initiative_example_call_tool.py b/public/examples/integrations/mcp-servers/linear/create_initiative_example_call_tool.py
new file mode 100644
index 000000000..afa350d47
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/create_initiative_example_call_tool.py
@@ -0,0 +1,30 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
+
+USER_ID = "{arcade_user_id}" # Unique identifier for your user (email, UUID, etc.)
+TOOL_NAME = "Linear.CreateInitiative"
+
+auth_response = client.tools.authorize(tool_name=TOOL_NAME, user_id=USER_ID)
+
+if auth_response.status != "completed":
+ print(f"Click this link to authorize: {auth_response.url}")
+
+# Wait for the authorization to complete
+client.auth.wait_for_completion(auth_response)
+
+tool_input = {
+ "name": "Q1 2025 Objectives",
+ "description": "Strategic goals for Q1 2025",
+ "status": "planned",
+ "target_date": "2025-03-31"
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+)
+print(json.dumps(response.output.value, indent=2))
+
diff --git a/public/examples/integrations/mcp-servers/linear/create_issue_example_call_tool.js b/public/examples/integrations/mcp-servers/linear/create_issue_example_call_tool.js
new file mode 100644
index 000000000..8ac5828e9
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/create_issue_example_call_tool.js
@@ -0,0 +1,34 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
+
+const USER_ID = "{arcade_user_id}"; // Unique identifier for your user (email, UUID, etc.)
+const TOOL_NAME = "Linear.CreateIssue";
+
+// Start the authorization process
+const authResponse = await client.tools.authorize({tool_name: TOOL_NAME, user_id: USER_ID});
+
+if (authResponse.status !== "completed") {
+ console.log(`Click this link to authorize: ${authResponse.url}`);
+}
+
+// Wait for the authorization to complete
+await client.auth.waitForCompletion(authResponse);
+
+const toolInput = {
+ "team": "Engineering",
+ "title": "Implement new authentication flow",
+ "description": "Add OAuth2 support for third-party integrations",
+ "priority": "high",
+ "labels_to_add": ["feature", "security"],
+ "due_date": "2025-02-15"
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
+
diff --git a/public/examples/integrations/mcp-servers/linear/create_issue_example_call_tool.py b/public/examples/integrations/mcp-servers/linear/create_issue_example_call_tool.py
new file mode 100644
index 000000000..d65b891ef
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/create_issue_example_call_tool.py
@@ -0,0 +1,32 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
+
+USER_ID = "{arcade_user_id}" # Unique identifier for your user (email, UUID, etc.)
+TOOL_NAME = "Linear.CreateIssue"
+
+auth_response = client.tools.authorize(tool_name=TOOL_NAME, user_id=USER_ID)
+
+if auth_response.status != "completed":
+ print(f"Click this link to authorize: {auth_response.url}")
+
+# Wait for the authorization to complete
+client.auth.wait_for_completion(auth_response)
+
+tool_input = {
+ "team": "Engineering",
+ "title": "Implement new authentication flow",
+ "description": "Add OAuth2 support for third-party integrations",
+ "priority": "high",
+ "labels_to_add": ["feature", "security"],
+ "due_date": "2025-02-15"
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+)
+print(json.dumps(response.output.value, indent=2))
+
diff --git a/public/examples/integrations/mcp-servers/linear/create_issue_relation_example_call_tool.js b/public/examples/integrations/mcp-servers/linear/create_issue_relation_example_call_tool.js
new file mode 100644
index 000000000..d1b90c3c4
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/create_issue_relation_example_call_tool.js
@@ -0,0 +1,31 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
+
+const USER_ID = "{arcade_user_id}"; // Unique identifier for your user (email, UUID, etc.)
+const TOOL_NAME = "Linear.CreateIssueRelation";
+
+// Start the authorization process
+const authResponse = await client.tools.authorize({tool_name: TOOL_NAME, user_id: USER_ID});
+
+if (authResponse.status !== "completed") {
+ console.log(`Click this link to authorize: ${authResponse.url}`);
+}
+
+// Wait for the authorization to complete
+await client.auth.waitForCompletion(authResponse);
+
+const toolInput = {
+ "issue": "PROJ-123",
+ "related_issue": "PROJ-456",
+ "relation_type": "blocks"
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
+
diff --git a/public/examples/integrations/mcp-servers/linear/create_issue_relation_example_call_tool.py b/public/examples/integrations/mcp-servers/linear/create_issue_relation_example_call_tool.py
new file mode 100644
index 000000000..a2cad45d5
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/create_issue_relation_example_call_tool.py
@@ -0,0 +1,29 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
+
+USER_ID = "{arcade_user_id}" # Unique identifier for your user (email, UUID, etc.)
+TOOL_NAME = "Linear.CreateIssueRelation"
+
+auth_response = client.tools.authorize(tool_name=TOOL_NAME, user_id=USER_ID)
+
+if auth_response.status != "completed":
+ print(f"Click this link to authorize: {auth_response.url}")
+
+# Wait for the authorization to complete
+client.auth.wait_for_completion(auth_response)
+
+tool_input = {
+ "issue": "PROJ-123",
+ "related_issue": "PROJ-456",
+ "relation_type": "blocks"
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+)
+print(json.dumps(response.output.value, indent=2))
+
diff --git a/public/examples/integrations/mcp-servers/linear/create_project_example_call_tool.js b/public/examples/integrations/mcp-servers/linear/create_project_example_call_tool.js
new file mode 100644
index 000000000..8ebdd561b
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/create_project_example_call_tool.js
@@ -0,0 +1,34 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
+
+const USER_ID = "{arcade_user_id}"; // Unique identifier for your user (email, UUID, etc.)
+const TOOL_NAME = "Linear.CreateProject";
+
+// Start the authorization process
+const authResponse = await client.tools.authorize({tool_name: TOOL_NAME, user_id: USER_ID});
+
+if (authResponse.status !== "completed") {
+ console.log(`Click this link to authorize: ${authResponse.url}`);
+}
+
+// Wait for the authorization to complete
+await client.auth.waitForCompletion(authResponse);
+
+const toolInput = {
+ "name": "New API Redesign",
+ "team": "Engineering",
+ "description": "Complete overhaul of the REST API",
+ "state": "planned",
+ "start_date": "2025-01-01",
+ "target_date": "2025-06-30"
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
+
diff --git a/public/examples/integrations/mcp-servers/linear/create_project_example_call_tool.py b/public/examples/integrations/mcp-servers/linear/create_project_example_call_tool.py
new file mode 100644
index 000000000..446a9b2f1
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/create_project_example_call_tool.py
@@ -0,0 +1,32 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
+
+USER_ID = "{arcade_user_id}" # Unique identifier for your user (email, UUID, etc.)
+TOOL_NAME = "Linear.CreateProject"
+
+auth_response = client.tools.authorize(tool_name=TOOL_NAME, user_id=USER_ID)
+
+if auth_response.status != "completed":
+ print(f"Click this link to authorize: {auth_response.url}")
+
+# Wait for the authorization to complete
+client.auth.wait_for_completion(auth_response)
+
+tool_input = {
+ "name": "New API Redesign",
+ "team": "Engineering",
+ "description": "Complete overhaul of the REST API",
+ "state": "planned",
+ "start_date": "2025-01-01",
+ "target_date": "2025-06-30"
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+)
+print(json.dumps(response.output.value, indent=2))
+
diff --git a/public/examples/integrations/mcp-servers/linear/create_project_update_example_call_tool.js b/public/examples/integrations/mcp-servers/linear/create_project_update_example_call_tool.js
new file mode 100644
index 000000000..1ec298f37
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/create_project_update_example_call_tool.js
@@ -0,0 +1,31 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
+
+const USER_ID = "{arcade_user_id}"; // Unique identifier for your user (email, UUID, etc.)
+const TOOL_NAME = "Linear.CreateProjectUpdate";
+
+// Start the authorization process
+const authResponse = await client.tools.authorize({tool_name: TOOL_NAME, user_id: USER_ID});
+
+if (authResponse.status !== "completed") {
+ console.log(`Click this link to authorize: ${authResponse.url}`);
+}
+
+// Wait for the authorization to complete
+await client.auth.waitForCompletion(authResponse);
+
+const toolInput = {
+ "project_id": "project-uuid-here",
+ "body": "## Weekly Progress Update\n\nCompleted the API integration this week.",
+ "health": "onTrack"
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
+
diff --git a/public/examples/integrations/mcp-servers/linear/create_project_update_example_call_tool.py b/public/examples/integrations/mcp-servers/linear/create_project_update_example_call_tool.py
new file mode 100644
index 000000000..baa80dbcb
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/create_project_update_example_call_tool.py
@@ -0,0 +1,29 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
+
+USER_ID = "{arcade_user_id}" # Unique identifier for your user (email, UUID, etc.)
+TOOL_NAME = "Linear.CreateProjectUpdate"
+
+auth_response = client.tools.authorize(tool_name=TOOL_NAME, user_id=USER_ID)
+
+if auth_response.status != "completed":
+ print(f"Click this link to authorize: {auth_response.url}")
+
+# Wait for the authorization to complete
+client.auth.wait_for_completion(auth_response)
+
+tool_input = {
+ "project_id": "project-uuid-here",
+ "body": "## Weekly Progress Update\n\nCompleted the API integration this week.",
+ "health": "onTrack"
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+)
+print(json.dumps(response.output.value, indent=2))
+
diff --git a/public/examples/integrations/mcp-servers/linear/get_cycle_example_call_tool.js b/public/examples/integrations/mcp-servers/linear/get_cycle_example_call_tool.js
new file mode 100644
index 000000000..84e7c577c
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/get_cycle_example_call_tool.js
@@ -0,0 +1,29 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
+
+const USER_ID = "{arcade_user_id}"; // Unique identifier for your user (email, UUID, etc.)
+const TOOL_NAME = "Linear.GetCycle";
+
+// Start the authorization process
+const authResponse = await client.tools.authorize({tool_name: TOOL_NAME, user_id: USER_ID});
+
+if (authResponse.status !== "completed") {
+ console.log(`Click this link to authorize: ${authResponse.url}`);
+}
+
+// Wait for the authorization to complete
+await client.auth.waitForCompletion(authResponse);
+
+const toolInput = {
+ "cycle_id": "cycle-uuid-here"
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
+
diff --git a/public/examples/integrations/mcp-servers/linear/get_cycle_example_call_tool.py b/public/examples/integrations/mcp-servers/linear/get_cycle_example_call_tool.py
new file mode 100644
index 000000000..15c38006b
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/get_cycle_example_call_tool.py
@@ -0,0 +1,27 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
+
+USER_ID = "{arcade_user_id}" # Unique identifier for your user (email, UUID, etc.)
+TOOL_NAME = "Linear.GetCycle"
+
+auth_response = client.tools.authorize(tool_name=TOOL_NAME, user_id=USER_ID)
+
+if auth_response.status != "completed":
+ print(f"Click this link to authorize: {auth_response.url}")
+
+# Wait for the authorization to complete
+client.auth.wait_for_completion(auth_response)
+
+tool_input = {
+ "cycle_id": "cycle-uuid-here"
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+)
+print(json.dumps(response.output.value, indent=2))
+
diff --git a/public/examples/integrations/mcp-servers/linear/get_initiative_description_example_call_tool.js b/public/examples/integrations/mcp-servers/linear/get_initiative_description_example_call_tool.js
new file mode 100644
index 000000000..5e8bce6d2
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/get_initiative_description_example_call_tool.js
@@ -0,0 +1,31 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
+
+const USER_ID = "{arcade_user_id}"; // Unique identifier for your user (email, UUID, etc.)
+const TOOL_NAME = "Linear.GetInitiativeDescription";
+
+// Start the authorization process
+const authResponse = await client.tools.authorize({tool_name: TOOL_NAME, user_id: USER_ID});
+
+if (authResponse.status !== "completed") {
+ console.log(`Click this link to authorize: ${authResponse.url}`);
+}
+
+// Wait for the authorization to complete
+await client.auth.waitForCompletion(authResponse);
+
+const toolInput = {
+ "initiative_id": "initiative-uuid-here",
+ "offset": 0,
+ "limit": 5000
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
+
diff --git a/public/examples/integrations/mcp-servers/linear/get_initiative_description_example_call_tool.py b/public/examples/integrations/mcp-servers/linear/get_initiative_description_example_call_tool.py
new file mode 100644
index 000000000..4a7bad8a5
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/get_initiative_description_example_call_tool.py
@@ -0,0 +1,29 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
+
+USER_ID = "{arcade_user_id}" # Unique identifier for your user (email, UUID, etc.)
+TOOL_NAME = "Linear.GetInitiativeDescription"
+
+auth_response = client.tools.authorize(tool_name=TOOL_NAME, user_id=USER_ID)
+
+if auth_response.status != "completed":
+ print(f"Click this link to authorize: {auth_response.url}")
+
+# Wait for the authorization to complete
+client.auth.wait_for_completion(auth_response)
+
+tool_input = {
+ "initiative_id": "initiative-uuid-here",
+ "offset": 0,
+ "limit": 5000
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+)
+print(json.dumps(response.output.value, indent=2))
+
diff --git a/public/examples/integrations/mcp-servers/linear/get_initiative_example_call_tool.js b/public/examples/integrations/mcp-servers/linear/get_initiative_example_call_tool.js
new file mode 100644
index 000000000..16fe04fea
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/get_initiative_example_call_tool.js
@@ -0,0 +1,32 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
+
+const USER_ID = "{arcade_user_id}"; // Unique identifier for your user (email, UUID, etc.)
+const TOOL_NAME = "Linear.GetInitiative";
+
+// Start the authorization process
+const authResponse = await client.tools.authorize({tool_name: TOOL_NAME, user_id: USER_ID});
+
+if (authResponse.status !== "completed") {
+ console.log(`Click this link to authorize: ${authResponse.url}`);
+}
+
+// Wait for the authorization to complete
+await client.auth.waitForCompletion(authResponse);
+
+const toolInput = {
+ "value": "Q4 Goals",
+ "lookup_by": "name",
+ "include_projects": true,
+ "auto_accept_matches": true
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
+
diff --git a/public/examples/integrations/mcp-servers/linear/get_initiative_example_call_tool.py b/public/examples/integrations/mcp-servers/linear/get_initiative_example_call_tool.py
new file mode 100644
index 000000000..4a23f2838
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/get_initiative_example_call_tool.py
@@ -0,0 +1,30 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
+
+USER_ID = "{arcade_user_id}" # Unique identifier for your user (email, UUID, etc.)
+TOOL_NAME = "Linear.GetInitiative"
+
+auth_response = client.tools.authorize(tool_name=TOOL_NAME, user_id=USER_ID)
+
+if auth_response.status != "completed":
+ print(f"Click this link to authorize: {auth_response.url}")
+
+# Wait for the authorization to complete
+client.auth.wait_for_completion(auth_response)
+
+tool_input = {
+ "value": "Q4 Goals",
+ "lookup_by": "name",
+ "include_projects": True,
+ "auto_accept_matches": True
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+)
+print(json.dumps(response.output.value, indent=2))
+
diff --git a/public/examples/integrations/mcp-servers/linear/get_issue_example_call_tool.js b/public/examples/integrations/mcp-servers/linear/get_issue_example_call_tool.js
index 953bd33eb..a5a612212 100644
--- a/public/examples/integrations/mcp-servers/linear/get_issue_example_call_tool.js
+++ b/public/examples/integrations/mcp-servers/linear/get_issue_example_call_tool.js
@@ -16,7 +16,11 @@ if (authResponse.status !== "completed") {
await client.auth.waitForCompletion(authResponse);
const toolInput = {
- "issue": "PROJ-123"
+ "issue_id": "PROJ-123",
+ "include_comments": true,
+ "include_attachments": true,
+ "include_relations": true,
+ "include_children": true
};
const response = await client.tools.execute({
diff --git a/public/examples/integrations/mcp-servers/linear/get_issue_example_call_tool.py b/public/examples/integrations/mcp-servers/linear/get_issue_example_call_tool.py
index 7fb398328..1420008bc 100644
--- a/public/examples/integrations/mcp-servers/linear/get_issue_example_call_tool.py
+++ b/public/examples/integrations/mcp-servers/linear/get_issue_example_call_tool.py
@@ -15,7 +15,11 @@
client.auth.wait_for_completion(auth_response)
tool_input = {
- "issue": "PROJ-123"
+ "issue_id": "PROJ-123",
+ "include_comments": True,
+ "include_attachments": True,
+ "include_relations": True,
+ "include_children": True
}
response = client.tools.execute(
diff --git a/public/examples/integrations/mcp-servers/linear/get_notifications_example_call_tool.js b/public/examples/integrations/mcp-servers/linear/get_notifications_example_call_tool.js
new file mode 100644
index 000000000..3af106a16
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/get_notifications_example_call_tool.js
@@ -0,0 +1,30 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
+
+const USER_ID = "{arcade_user_id}"; // Unique identifier for your user (email, UUID, etc.)
+const TOOL_NAME = "Linear.GetNotifications";
+
+// Start the authorization process
+const authResponse = await client.tools.authorize({tool_name: TOOL_NAME, user_id: USER_ID});
+
+if (authResponse.status !== "completed") {
+ console.log(`Click this link to authorize: ${authResponse.url}`);
+}
+
+// Wait for the authorization to complete
+await client.auth.waitForCompletion(authResponse);
+
+const toolInput = {
+ "unread_only": true,
+ "limit": 20
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
+
diff --git a/public/examples/integrations/mcp-servers/linear/get_notifications_example_call_tool.py b/public/examples/integrations/mcp-servers/linear/get_notifications_example_call_tool.py
new file mode 100644
index 000000000..d7c3c339f
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/get_notifications_example_call_tool.py
@@ -0,0 +1,28 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
+
+USER_ID = "{arcade_user_id}" # Unique identifier for your user (email, UUID, etc.)
+TOOL_NAME = "Linear.GetNotifications"
+
+auth_response = client.tools.authorize(tool_name=TOOL_NAME, user_id=USER_ID)
+
+if auth_response.status != "completed":
+ print(f"Click this link to authorize: {auth_response.url}")
+
+# Wait for the authorization to complete
+client.auth.wait_for_completion(auth_response)
+
+tool_input = {
+ "unread_only": True,
+ "limit": 20
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+)
+print(json.dumps(response.output.value, indent=2))
+
diff --git a/public/examples/integrations/mcp-servers/linear/get_project_description_example_call_tool.js b/public/examples/integrations/mcp-servers/linear/get_project_description_example_call_tool.js
new file mode 100644
index 000000000..b919b71e7
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/get_project_description_example_call_tool.js
@@ -0,0 +1,31 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
+
+const USER_ID = "{arcade_user_id}"; // Unique identifier for your user (email, UUID, etc.)
+const TOOL_NAME = "Linear.GetProjectDescription";
+
+// Start the authorization process
+const authResponse = await client.tools.authorize({tool_name: TOOL_NAME, user_id: USER_ID});
+
+if (authResponse.status !== "completed") {
+ console.log(`Click this link to authorize: ${authResponse.url}`);
+}
+
+// Wait for the authorization to complete
+await client.auth.waitForCompletion(authResponse);
+
+const toolInput = {
+ "project_id": "project-uuid-here",
+ "offset": 0,
+ "limit": 5000
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
+
diff --git a/public/examples/integrations/mcp-servers/linear/get_project_description_example_call_tool.py b/public/examples/integrations/mcp-servers/linear/get_project_description_example_call_tool.py
new file mode 100644
index 000000000..8f812a5c3
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/get_project_description_example_call_tool.py
@@ -0,0 +1,29 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
+
+USER_ID = "{arcade_user_id}" # Unique identifier for your user (email, UUID, etc.)
+TOOL_NAME = "Linear.GetProjectDescription"
+
+auth_response = client.tools.authorize(tool_name=TOOL_NAME, user_id=USER_ID)
+
+if auth_response.status != "completed":
+ print(f"Click this link to authorize: {auth_response.url}")
+
+# Wait for the authorization to complete
+client.auth.wait_for_completion(auth_response)
+
+tool_input = {
+ "project_id": "project-uuid-here",
+ "offset": 0,
+ "limit": 5000
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+)
+print(json.dumps(response.output.value, indent=2))
+
diff --git a/public/examples/integrations/mcp-servers/linear/get_project_example_call_tool.js b/public/examples/integrations/mcp-servers/linear/get_project_example_call_tool.js
new file mode 100644
index 000000000..0cb341a3d
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/get_project_example_call_tool.js
@@ -0,0 +1,34 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
+
+const USER_ID = "{arcade_user_id}"; // Unique identifier for your user (email, UUID, etc.)
+const TOOL_NAME = "Linear.GetProject";
+
+// Start the authorization process
+const authResponse = await client.tools.authorize({tool_name: TOOL_NAME, user_id: USER_ID});
+
+if (authResponse.status !== "completed") {
+ console.log(`Click this link to authorize: ${authResponse.url}`);
+}
+
+// Wait for the authorization to complete
+await client.auth.waitForCompletion(authResponse);
+
+const toolInput = {
+ "value": "API Redesign",
+ "lookup_by": "name",
+ "include_milestones": true,
+ "include_members": true,
+ "include_issues": true,
+ "auto_accept_matches": true
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
+
diff --git a/public/examples/integrations/mcp-servers/linear/get_project_example_call_tool.py b/public/examples/integrations/mcp-servers/linear/get_project_example_call_tool.py
new file mode 100644
index 000000000..b790075f9
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/get_project_example_call_tool.py
@@ -0,0 +1,32 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
+
+USER_ID = "{arcade_user_id}" # Unique identifier for your user (email, UUID, etc.)
+TOOL_NAME = "Linear.GetProject"
+
+auth_response = client.tools.authorize(tool_name=TOOL_NAME, user_id=USER_ID)
+
+if auth_response.status != "completed":
+ print(f"Click this link to authorize: {auth_response.url}")
+
+# Wait for the authorization to complete
+client.auth.wait_for_completion(auth_response)
+
+tool_input = {
+ "value": "API Redesign",
+ "lookup_by": "name",
+ "include_milestones": True,
+ "include_members": True,
+ "include_issues": True,
+ "auto_accept_matches": True
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+)
+print(json.dumps(response.output.value, indent=2))
+
diff --git a/public/examples/integrations/mcp-servers/linear/get_recent_activity_example_call_tool.js b/public/examples/integrations/mcp-servers/linear/get_recent_activity_example_call_tool.js
new file mode 100644
index 000000000..0bc5a4606
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/get_recent_activity_example_call_tool.js
@@ -0,0 +1,30 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
+
+const USER_ID = "{arcade_user_id}"; // Unique identifier for your user (email, UUID, etc.)
+const TOOL_NAME = "Linear.GetRecentActivity";
+
+// Start the authorization process
+const authResponse = await client.tools.authorize({tool_name: TOOL_NAME, user_id: USER_ID});
+
+if (authResponse.status !== "completed") {
+ console.log(`Click this link to authorize: ${authResponse.url}`);
+}
+
+// Wait for the authorization to complete
+await client.auth.waitForCompletion(authResponse);
+
+const toolInput = {
+ "days": 30,
+ "limit": 20
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
+
diff --git a/public/examples/integrations/mcp-servers/linear/get_recent_activity_example_call_tool.py b/public/examples/integrations/mcp-servers/linear/get_recent_activity_example_call_tool.py
new file mode 100644
index 000000000..5787ee0db
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/get_recent_activity_example_call_tool.py
@@ -0,0 +1,28 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
+
+USER_ID = "{arcade_user_id}" # Unique identifier for your user (email, UUID, etc.)
+TOOL_NAME = "Linear.GetRecentActivity"
+
+auth_response = client.tools.authorize(tool_name=TOOL_NAME, user_id=USER_ID)
+
+if auth_response.status != "completed":
+ print(f"Click this link to authorize: {auth_response.url}")
+
+# Wait for the authorization to complete
+client.auth.wait_for_completion(auth_response)
+
+tool_input = {
+ "days": 30,
+ "limit": 20
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+)
+print(json.dumps(response.output.value, indent=2))
+
diff --git a/public/examples/integrations/mcp-servers/linear/get_team_example_call_tool.js b/public/examples/integrations/mcp-servers/linear/get_team_example_call_tool.js
new file mode 100644
index 000000000..3dd4e00f4
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/get_team_example_call_tool.js
@@ -0,0 +1,31 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
+
+const USER_ID = "{arcade_user_id}"; // Unique identifier for your user (email, UUID, etc.)
+const TOOL_NAME = "Linear.GetTeam";
+
+// Start the authorization process
+const authResponse = await client.tools.authorize({tool_name: TOOL_NAME, user_id: USER_ID});
+
+if (authResponse.status !== "completed") {
+ console.log(`Click this link to authorize: ${authResponse.url}`);
+}
+
+// Wait for the authorization to complete
+await client.auth.waitForCompletion(authResponse);
+
+const toolInput = {
+ "value": "Engineering",
+ "lookup_by": "name",
+ "auto_accept_matches": true
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
+
diff --git a/public/examples/integrations/mcp-servers/linear/get_team_example_call_tool.py b/public/examples/integrations/mcp-servers/linear/get_team_example_call_tool.py
new file mode 100644
index 000000000..7ba7c6bf7
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/get_team_example_call_tool.py
@@ -0,0 +1,29 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
+
+USER_ID = "{arcade_user_id}" # Unique identifier for your user (email, UUID, etc.)
+TOOL_NAME = "Linear.GetTeam"
+
+auth_response = client.tools.authorize(tool_name=TOOL_NAME, user_id=USER_ID)
+
+if auth_response.status != "completed":
+ print(f"Click this link to authorize: {auth_response.url}")
+
+# Wait for the authorization to complete
+client.auth.wait_for_completion(auth_response)
+
+tool_input = {
+ "value": "Engineering",
+ "lookup_by": "name",
+ "auto_accept_matches": True
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+)
+print(json.dumps(response.output.value, indent=2))
+
diff --git a/public/examples/integrations/mcp-servers/linear/get_teams_example_call_tool.js b/public/examples/integrations/mcp-servers/linear/get_teams_example_call_tool.js
index e69de29bb..3c28c79e2 100644
--- a/public/examples/integrations/mcp-servers/linear/get_teams_example_call_tool.js
+++ b/public/examples/integrations/mcp-servers/linear/get_teams_example_call_tool.js
@@ -0,0 +1,31 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
+
+const USER_ID = "{arcade_user_id}"; // Unique identifier for your user (email, UUID, etc.)
+const TOOL_NAME = "Linear.ListTeams";
+
+// Start the authorization process
+const authResponse = await client.tools.authorize({tool_name: TOOL_NAME, user_id: USER_ID});
+
+if (authResponse.status !== "completed") {
+ console.log(`Click this link to authorize: ${authResponse.url}`);
+}
+
+// Wait for the authorization to complete
+await client.auth.waitForCompletion(authResponse);
+
+const toolInput = {
+ "keywords": "Backend",
+ "include_archived": false,
+ "limit": 20
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
+
diff --git a/public/examples/integrations/mcp-servers/linear/get_teams_example_call_tool.py b/public/examples/integrations/mcp-servers/linear/get_teams_example_call_tool.py
index 1ed6f67ed..0f2dc5592 100644
--- a/public/examples/integrations/mcp-servers/linear/get_teams_example_call_tool.py
+++ b/public/examples/integrations/mcp-servers/linear/get_teams_example_call_tool.py
@@ -4,7 +4,7 @@
client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
USER_ID = "{arcade_user_id}" # Unique identifier for your user (email, UUID, etc.)
-TOOL_NAME = "Linear.GetTeams"
+TOOL_NAME = "Linear.ListTeams"
auth_response = client.tools.authorize(tool_name=TOOL_NAME, user_id=USER_ID)
@@ -15,8 +15,9 @@
client.auth.wait_for_completion(auth_response)
tool_input = {
- "team_name": "Backend",
- "created_after": "December 21, 2012"
+ "keywords": "Backend",
+ "include_archived": False,
+ "limit": 20
}
response = client.tools.execute(
diff --git a/public/examples/integrations/mcp-servers/linear/link_github_to_issue_example_call_tool.js b/public/examples/integrations/mcp-servers/linear/link_github_to_issue_example_call_tool.js
new file mode 100644
index 000000000..a48eb5c05
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/link_github_to_issue_example_call_tool.js
@@ -0,0 +1,31 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
+
+const USER_ID = "{arcade_user_id}"; // Unique identifier for your user (email, UUID, etc.)
+const TOOL_NAME = "Linear.LinkGithubToIssue";
+
+// Start the authorization process
+const authResponse = await client.tools.authorize({tool_name: TOOL_NAME, user_id: USER_ID});
+
+if (authResponse.status !== "completed") {
+ console.log(`Click this link to authorize: ${authResponse.url}`);
+}
+
+// Wait for the authorization to complete
+await client.auth.waitForCompletion(authResponse);
+
+const toolInput = {
+ "issue": "PROJ-123",
+ "github_url": "https://github.com/owner/repo/pull/42",
+ "title": "Fix authentication bug"
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
+
diff --git a/public/examples/integrations/mcp-servers/linear/link_github_to_issue_example_call_tool.py b/public/examples/integrations/mcp-servers/linear/link_github_to_issue_example_call_tool.py
new file mode 100644
index 000000000..e1c583a3f
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/link_github_to_issue_example_call_tool.py
@@ -0,0 +1,29 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
+
+USER_ID = "{arcade_user_id}" # Unique identifier for your user (email, UUID, etc.)
+TOOL_NAME = "Linear.LinkGithubToIssue"
+
+auth_response = client.tools.authorize(tool_name=TOOL_NAME, user_id=USER_ID)
+
+if auth_response.status != "completed":
+ print(f"Click this link to authorize: {auth_response.url}")
+
+# Wait for the authorization to complete
+client.auth.wait_for_completion(auth_response)
+
+tool_input = {
+ "issue": "PROJ-123",
+ "github_url": "https://github.com/owner/repo/pull/42",
+ "title": "Fix authentication bug"
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+)
+print(json.dumps(response.output.value, indent=2))
+
diff --git a/public/examples/integrations/mcp-servers/linear/list_comments_example_call_tool.js b/public/examples/integrations/mcp-servers/linear/list_comments_example_call_tool.js
new file mode 100644
index 000000000..343ff8325
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/list_comments_example_call_tool.js
@@ -0,0 +1,30 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
+
+const USER_ID = "{arcade_user_id}"; // Unique identifier for your user (email, UUID, etc.)
+const TOOL_NAME = "Linear.ListComments";
+
+// Start the authorization process
+const authResponse = await client.tools.authorize({tool_name: TOOL_NAME, user_id: USER_ID});
+
+if (authResponse.status !== "completed") {
+ console.log(`Click this link to authorize: ${authResponse.url}`);
+}
+
+// Wait for the authorization to complete
+await client.auth.waitForCompletion(authResponse);
+
+const toolInput = {
+ "issue": "PROJ-123",
+ "limit": 20
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
+
diff --git a/public/examples/integrations/mcp-servers/linear/list_comments_example_call_tool.py b/public/examples/integrations/mcp-servers/linear/list_comments_example_call_tool.py
new file mode 100644
index 000000000..98161d4a9
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/list_comments_example_call_tool.py
@@ -0,0 +1,28 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
+
+USER_ID = "{arcade_user_id}" # Unique identifier for your user (email, UUID, etc.)
+TOOL_NAME = "Linear.ListComments"
+
+auth_response = client.tools.authorize(tool_name=TOOL_NAME, user_id=USER_ID)
+
+if auth_response.status != "completed":
+ print(f"Click this link to authorize: {auth_response.url}")
+
+# Wait for the authorization to complete
+client.auth.wait_for_completion(auth_response)
+
+tool_input = {
+ "issue": "PROJ-123",
+ "limit": 20
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+)
+print(json.dumps(response.output.value, indent=2))
+
diff --git a/public/examples/integrations/mcp-servers/linear/list_cycles_example_call_tool.js b/public/examples/integrations/mcp-servers/linear/list_cycles_example_call_tool.js
new file mode 100644
index 000000000..aa2aca2de
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/list_cycles_example_call_tool.js
@@ -0,0 +1,31 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
+
+const USER_ID = "{arcade_user_id}"; // Unique identifier for your user (email, UUID, etc.)
+const TOOL_NAME = "Linear.ListCycles";
+
+// Start the authorization process
+const authResponse = await client.tools.authorize({tool_name: TOOL_NAME, user_id: USER_ID});
+
+if (authResponse.status !== "completed") {
+ console.log(`Click this link to authorize: ${authResponse.url}`);
+}
+
+// Wait for the authorization to complete
+await client.auth.waitForCompletion(authResponse);
+
+const toolInput = {
+ "team": "Engineering",
+ "active_only": true,
+ "limit": 20
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
+
diff --git a/public/examples/integrations/mcp-servers/linear/list_cycles_example_call_tool.py b/public/examples/integrations/mcp-servers/linear/list_cycles_example_call_tool.py
new file mode 100644
index 000000000..ec88f0ec4
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/list_cycles_example_call_tool.py
@@ -0,0 +1,29 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
+
+USER_ID = "{arcade_user_id}" # Unique identifier for your user (email, UUID, etc.)
+TOOL_NAME = "Linear.ListCycles"
+
+auth_response = client.tools.authorize(tool_name=TOOL_NAME, user_id=USER_ID)
+
+if auth_response.status != "completed":
+ print(f"Click this link to authorize: {auth_response.url}")
+
+# Wait for the authorization to complete
+client.auth.wait_for_completion(auth_response)
+
+tool_input = {
+ "team": "Engineering",
+ "active_only": True,
+ "limit": 20
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+)
+print(json.dumps(response.output.value, indent=2))
+
diff --git a/public/examples/integrations/mcp-servers/linear/list_initiatives_example_call_tool.js b/public/examples/integrations/mcp-servers/linear/list_initiatives_example_call_tool.js
new file mode 100644
index 000000000..02beda10c
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/list_initiatives_example_call_tool.js
@@ -0,0 +1,31 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
+
+const USER_ID = "{arcade_user_id}"; // Unique identifier for your user (email, UUID, etc.)
+const TOOL_NAME = "Linear.ListInitiatives";
+
+// Start the authorization process
+const authResponse = await client.tools.authorize({tool_name: TOOL_NAME, user_id: USER_ID});
+
+if (authResponse.status !== "completed") {
+ console.log(`Click this link to authorize: ${authResponse.url}`);
+}
+
+// Wait for the authorization to complete
+await client.auth.waitForCompletion(authResponse);
+
+const toolInput = {
+ "keywords": "Q4",
+ "state": "started",
+ "limit": 20
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
+
diff --git a/public/examples/integrations/mcp-servers/linear/list_initiatives_example_call_tool.py b/public/examples/integrations/mcp-servers/linear/list_initiatives_example_call_tool.py
new file mode 100644
index 000000000..13c5254b1
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/list_initiatives_example_call_tool.py
@@ -0,0 +1,29 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
+
+USER_ID = "{arcade_user_id}" # Unique identifier for your user (email, UUID, etc.)
+TOOL_NAME = "Linear.ListInitiatives"
+
+auth_response = client.tools.authorize(tool_name=TOOL_NAME, user_id=USER_ID)
+
+if auth_response.status != "completed":
+ print(f"Click this link to authorize: {auth_response.url}")
+
+# Wait for the authorization to complete
+client.auth.wait_for_completion(auth_response)
+
+tool_input = {
+ "keywords": "Q4",
+ "state": "started",
+ "limit": 20
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+)
+print(json.dumps(response.output.value, indent=2))
+
diff --git a/public/examples/integrations/mcp-servers/linear/list_issues_example_call_tool.js b/public/examples/integrations/mcp-servers/linear/list_issues_example_call_tool.js
new file mode 100644
index 000000000..2519e600e
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/list_issues_example_call_tool.js
@@ -0,0 +1,32 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
+
+const USER_ID = "{arcade_user_id}"; // Unique identifier for your user (email, UUID, etc.)
+const TOOL_NAME = "Linear.ListIssues";
+
+// Start the authorization process
+const authResponse = await client.tools.authorize({tool_name: TOOL_NAME, user_id: USER_ID});
+
+if (authResponse.status !== "completed") {
+ console.log(`Click this link to authorize: ${authResponse.url}`);
+}
+
+// Wait for the authorization to complete
+await client.auth.waitForCompletion(authResponse);
+
+const toolInput = {
+ "team": "Engineering",
+ "state": "In Progress",
+ "assignee": "@me",
+ "limit": 20
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
+
diff --git a/public/examples/integrations/mcp-servers/linear/list_issues_example_call_tool.py b/public/examples/integrations/mcp-servers/linear/list_issues_example_call_tool.py
new file mode 100644
index 000000000..71b0dfda2
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/list_issues_example_call_tool.py
@@ -0,0 +1,30 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
+
+USER_ID = "{arcade_user_id}" # Unique identifier for your user (email, UUID, etc.)
+TOOL_NAME = "Linear.ListIssues"
+
+auth_response = client.tools.authorize(tool_name=TOOL_NAME, user_id=USER_ID)
+
+if auth_response.status != "completed":
+ print(f"Click this link to authorize: {auth_response.url}")
+
+# Wait for the authorization to complete
+client.auth.wait_for_completion(auth_response)
+
+tool_input = {
+ "team": "Engineering",
+ "state": "In Progress",
+ "assignee": "@me",
+ "limit": 20
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+)
+print(json.dumps(response.output.value, indent=2))
+
diff --git a/public/examples/integrations/mcp-servers/linear/list_labels_example_call_tool.js b/public/examples/integrations/mcp-servers/linear/list_labels_example_call_tool.js
new file mode 100644
index 000000000..c0f8f9e2d
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/list_labels_example_call_tool.js
@@ -0,0 +1,29 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
+
+const USER_ID = "{arcade_user_id}"; // Unique identifier for your user (email, UUID, etc.)
+const TOOL_NAME = "Linear.ListLabels";
+
+// Start the authorization process
+const authResponse = await client.tools.authorize({tool_name: TOOL_NAME, user_id: USER_ID});
+
+if (authResponse.status !== "completed") {
+ console.log(`Click this link to authorize: ${authResponse.url}`);
+}
+
+// Wait for the authorization to complete
+await client.auth.waitForCompletion(authResponse);
+
+const toolInput = {
+ "limit": 50
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
+
diff --git a/public/examples/integrations/mcp-servers/linear/list_labels_example_call_tool.py b/public/examples/integrations/mcp-servers/linear/list_labels_example_call_tool.py
new file mode 100644
index 000000000..9cc21b07c
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/list_labels_example_call_tool.py
@@ -0,0 +1,27 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
+
+USER_ID = "{arcade_user_id}" # Unique identifier for your user (email, UUID, etc.)
+TOOL_NAME = "Linear.ListLabels"
+
+auth_response = client.tools.authorize(tool_name=TOOL_NAME, user_id=USER_ID)
+
+if auth_response.status != "completed":
+ print(f"Click this link to authorize: {auth_response.url}")
+
+# Wait for the authorization to complete
+client.auth.wait_for_completion(auth_response)
+
+tool_input = {
+ "limit": 50
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+)
+print(json.dumps(response.output.value, indent=2))
+
diff --git a/public/examples/integrations/mcp-servers/linear/list_projects_example_call_tool.js b/public/examples/integrations/mcp-servers/linear/list_projects_example_call_tool.js
new file mode 100644
index 000000000..178f07bf4
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/list_projects_example_call_tool.js
@@ -0,0 +1,32 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
+
+const USER_ID = "{arcade_user_id}"; // Unique identifier for your user (email, UUID, etc.)
+const TOOL_NAME = "Linear.ListProjects";
+
+// Start the authorization process
+const authResponse = await client.tools.authorize({tool_name: TOOL_NAME, user_id: USER_ID});
+
+if (authResponse.status !== "completed") {
+ console.log(`Click this link to authorize: ${authResponse.url}`);
+}
+
+// Wait for the authorization to complete
+await client.auth.waitForCompletion(authResponse);
+
+const toolInput = {
+ "keywords": "API",
+ "state": "started",
+ "team": "Engineering",
+ "limit": 20
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
+
diff --git a/public/examples/integrations/mcp-servers/linear/list_projects_example_call_tool.py b/public/examples/integrations/mcp-servers/linear/list_projects_example_call_tool.py
new file mode 100644
index 000000000..dfb5544df
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/list_projects_example_call_tool.py
@@ -0,0 +1,30 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
+
+USER_ID = "{arcade_user_id}" # Unique identifier for your user (email, UUID, etc.)
+TOOL_NAME = "Linear.ListProjects"
+
+auth_response = client.tools.authorize(tool_name=TOOL_NAME, user_id=USER_ID)
+
+if auth_response.status != "completed":
+ print(f"Click this link to authorize: {auth_response.url}")
+
+# Wait for the authorization to complete
+client.auth.wait_for_completion(auth_response)
+
+tool_input = {
+ "keywords": "API",
+ "state": "started",
+ "team": "Engineering",
+ "limit": 20
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+)
+print(json.dumps(response.output.value, indent=2))
+
diff --git a/public/examples/integrations/mcp-servers/linear/list_teams_example_call_tool.js b/public/examples/integrations/mcp-servers/linear/list_teams_example_call_tool.js
new file mode 100644
index 000000000..d440ec14d
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/list_teams_example_call_tool.js
@@ -0,0 +1,31 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
+
+const USER_ID = "{arcade_user_id}"; // Unique identifier for your user (email, UUID, etc.)
+const TOOL_NAME = "Linear.ListTeams";
+
+// Start the authorization process
+const authResponse = await client.tools.authorize({tool_name: TOOL_NAME, user_id: USER_ID});
+
+if (authResponse.status !== "completed") {
+ console.log(`Click this link to authorize: ${authResponse.url}`);
+}
+
+// Wait for the authorization to complete
+await client.auth.waitForCompletion(authResponse);
+
+const toolInput = {
+ "keywords": "Engineering",
+ "include_archived": false,
+ "limit": 20
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
+
diff --git a/public/examples/integrations/mcp-servers/linear/list_teams_example_call_tool.py b/public/examples/integrations/mcp-servers/linear/list_teams_example_call_tool.py
new file mode 100644
index 000000000..5ad33ece0
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/list_teams_example_call_tool.py
@@ -0,0 +1,29 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
+
+USER_ID = "{arcade_user_id}" # Unique identifier for your user (email, UUID, etc.)
+TOOL_NAME = "Linear.ListTeams"
+
+auth_response = client.tools.authorize(tool_name=TOOL_NAME, user_id=USER_ID)
+
+if auth_response.status != "completed":
+ print(f"Click this link to authorize: {auth_response.url}")
+
+# Wait for the authorization to complete
+client.auth.wait_for_completion(auth_response)
+
+tool_input = {
+ "keywords": "Engineering",
+ "include_archived": False,
+ "limit": 20
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+)
+print(json.dumps(response.output.value, indent=2))
+
diff --git a/public/examples/integrations/mcp-servers/linear/list_workflow_states_example_call_tool.js b/public/examples/integrations/mcp-servers/linear/list_workflow_states_example_call_tool.js
new file mode 100644
index 000000000..06c2a8181
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/list_workflow_states_example_call_tool.js
@@ -0,0 +1,31 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
+
+const USER_ID = "{arcade_user_id}"; // Unique identifier for your user (email, UUID, etc.)
+const TOOL_NAME = "Linear.ListWorkflowStates";
+
+// Start the authorization process
+const authResponse = await client.tools.authorize({tool_name: TOOL_NAME, user_id: USER_ID});
+
+if (authResponse.status !== "completed") {
+ console.log(`Click this link to authorize: ${authResponse.url}`);
+}
+
+// Wait for the authorization to complete
+await client.auth.waitForCompletion(authResponse);
+
+const toolInput = {
+ "team": "Engineering",
+ "state_type": "started",
+ "limit": 50
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
+
diff --git a/public/examples/integrations/mcp-servers/linear/list_workflow_states_example_call_tool.py b/public/examples/integrations/mcp-servers/linear/list_workflow_states_example_call_tool.py
new file mode 100644
index 000000000..3fae94c81
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/list_workflow_states_example_call_tool.py
@@ -0,0 +1,29 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
+
+USER_ID = "{arcade_user_id}" # Unique identifier for your user (email, UUID, etc.)
+TOOL_NAME = "Linear.ListWorkflowStates"
+
+auth_response = client.tools.authorize(tool_name=TOOL_NAME, user_id=USER_ID)
+
+if auth_response.status != "completed":
+ print(f"Click this link to authorize: {auth_response.url}")
+
+# Wait for the authorization to complete
+client.auth.wait_for_completion(auth_response)
+
+tool_input = {
+ "team": "Engineering",
+ "state_type": "started",
+ "limit": 50
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+)
+print(json.dumps(response.output.value, indent=2))
+
diff --git a/public/examples/integrations/mcp-servers/linear/manage_issue_subscription_example_call_tool.js b/public/examples/integrations/mcp-servers/linear/manage_issue_subscription_example_call_tool.js
new file mode 100644
index 000000000..0ad8e01a9
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/manage_issue_subscription_example_call_tool.js
@@ -0,0 +1,30 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
+
+const USER_ID = "{arcade_user_id}"; // Unique identifier for your user (email, UUID, etc.)
+const TOOL_NAME = "Linear.ManageIssueSubscription";
+
+// Start the authorization process
+const authResponse = await client.tools.authorize({tool_name: TOOL_NAME, user_id: USER_ID});
+
+if (authResponse.status !== "completed") {
+ console.log(`Click this link to authorize: ${authResponse.url}`);
+}
+
+// Wait for the authorization to complete
+await client.auth.waitForCompletion(authResponse);
+
+const toolInput = {
+ "issue": "PROJ-123",
+ "subscribe": true
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
+
diff --git a/public/examples/integrations/mcp-servers/linear/manage_issue_subscription_example_call_tool.py b/public/examples/integrations/mcp-servers/linear/manage_issue_subscription_example_call_tool.py
new file mode 100644
index 000000000..3b8ea96fa
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/manage_issue_subscription_example_call_tool.py
@@ -0,0 +1,28 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
+
+USER_ID = "{arcade_user_id}" # Unique identifier for your user (email, UUID, etc.)
+TOOL_NAME = "Linear.ManageIssueSubscription"
+
+auth_response = client.tools.authorize(tool_name=TOOL_NAME, user_id=USER_ID)
+
+if auth_response.status != "completed":
+ print(f"Click this link to authorize: {auth_response.url}")
+
+# Wait for the authorization to complete
+client.auth.wait_for_completion(auth_response)
+
+tool_input = {
+ "issue": "PROJ-123",
+ "subscribe": True
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+)
+print(json.dumps(response.output.value, indent=2))
+
diff --git a/public/examples/integrations/mcp-servers/linear/reply_to_comment_example_call_tool.js b/public/examples/integrations/mcp-servers/linear/reply_to_comment_example_call_tool.js
new file mode 100644
index 000000000..c2ec6aaec
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/reply_to_comment_example_call_tool.js
@@ -0,0 +1,31 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
+
+const USER_ID = "{arcade_user_id}"; // Unique identifier for your user (email, UUID, etc.)
+const TOOL_NAME = "Linear.ReplyToComment";
+
+// Start the authorization process
+const authResponse = await client.tools.authorize({tool_name: TOOL_NAME, user_id: USER_ID});
+
+if (authResponse.status !== "completed") {
+ console.log(`Click this link to authorize: ${authResponse.url}`);
+}
+
+// Wait for the authorization to complete
+await client.auth.waitForCompletion(authResponse);
+
+const toolInput = {
+ "issue": "PROJ-123",
+ "parent_comment_id": "parent-comment-uuid",
+ "body": "This is a threaded reply in **Markdown** format."
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
+
diff --git a/public/examples/integrations/mcp-servers/linear/reply_to_comment_example_call_tool.py b/public/examples/integrations/mcp-servers/linear/reply_to_comment_example_call_tool.py
new file mode 100644
index 000000000..53343e77a
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/reply_to_comment_example_call_tool.py
@@ -0,0 +1,29 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
+
+USER_ID = "{arcade_user_id}" # Unique identifier for your user (email, UUID, etc.)
+TOOL_NAME = "Linear.ReplyToComment"
+
+auth_response = client.tools.authorize(tool_name=TOOL_NAME, user_id=USER_ID)
+
+if auth_response.status != "completed":
+ print(f"Click this link to authorize: {auth_response.url}")
+
+# Wait for the authorization to complete
+client.auth.wait_for_completion(auth_response)
+
+tool_input = {
+ "issue": "PROJ-123",
+ "parent_comment_id": "parent-comment-uuid",
+ "body": "This is a threaded reply in **Markdown** format."
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+)
+print(json.dumps(response.output.value, indent=2))
+
diff --git a/public/examples/integrations/mcp-servers/linear/transition_issue_state_example_call_tool.js b/public/examples/integrations/mcp-servers/linear/transition_issue_state_example_call_tool.js
new file mode 100644
index 000000000..e901f4aba
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/transition_issue_state_example_call_tool.js
@@ -0,0 +1,31 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
+
+const USER_ID = "{arcade_user_id}"; // Unique identifier for your user (email, UUID, etc.)
+const TOOL_NAME = "Linear.TransitionIssueState";
+
+// Start the authorization process
+const authResponse = await client.tools.authorize({tool_name: TOOL_NAME, user_id: USER_ID});
+
+if (authResponse.status !== "completed") {
+ console.log(`Click this link to authorize: ${authResponse.url}`);
+}
+
+// Wait for the authorization to complete
+await client.auth.waitForCompletion(authResponse);
+
+const toolInput = {
+ "issue_id": "PROJ-123",
+ "target_state": "Done",
+ "auto_accept_matches": true
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
+
diff --git a/public/examples/integrations/mcp-servers/linear/transition_issue_state_example_call_tool.py b/public/examples/integrations/mcp-servers/linear/transition_issue_state_example_call_tool.py
new file mode 100644
index 000000000..611ad072a
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/transition_issue_state_example_call_tool.py
@@ -0,0 +1,29 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
+
+USER_ID = "{arcade_user_id}" # Unique identifier for your user (email, UUID, etc.)
+TOOL_NAME = "Linear.TransitionIssueState"
+
+auth_response = client.tools.authorize(tool_name=TOOL_NAME, user_id=USER_ID)
+
+if auth_response.status != "completed":
+ print(f"Click this link to authorize: {auth_response.url}")
+
+# Wait for the authorization to complete
+client.auth.wait_for_completion(auth_response)
+
+tool_input = {
+ "issue_id": "PROJ-123",
+ "target_state": "Done",
+ "auto_accept_matches": True
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+)
+print(json.dumps(response.output.value, indent=2))
+
diff --git a/public/examples/integrations/mcp-servers/linear/update_comment_example_call_tool.js b/public/examples/integrations/mcp-servers/linear/update_comment_example_call_tool.js
new file mode 100644
index 000000000..22f274bb7
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/update_comment_example_call_tool.js
@@ -0,0 +1,30 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
+
+const USER_ID = "{arcade_user_id}"; // Unique identifier for your user (email, UUID, etc.)
+const TOOL_NAME = "Linear.UpdateComment";
+
+// Start the authorization process
+const authResponse = await client.tools.authorize({tool_name: TOOL_NAME, user_id: USER_ID});
+
+if (authResponse.status !== "completed") {
+ console.log(`Click this link to authorize: ${authResponse.url}`);
+}
+
+// Wait for the authorization to complete
+await client.auth.waitForCompletion(authResponse);
+
+const toolInput = {
+ "comment_id": "comment-uuid-here",
+ "body": "Updated comment content in **Markdown** format."
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
+
diff --git a/public/examples/integrations/mcp-servers/linear/update_comment_example_call_tool.py b/public/examples/integrations/mcp-servers/linear/update_comment_example_call_tool.py
new file mode 100644
index 000000000..9b9985a5a
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/update_comment_example_call_tool.py
@@ -0,0 +1,28 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
+
+USER_ID = "{arcade_user_id}" # Unique identifier for your user (email, UUID, etc.)
+TOOL_NAME = "Linear.UpdateComment"
+
+auth_response = client.tools.authorize(tool_name=TOOL_NAME, user_id=USER_ID)
+
+if auth_response.status != "completed":
+ print(f"Click this link to authorize: {auth_response.url}")
+
+# Wait for the authorization to complete
+client.auth.wait_for_completion(auth_response)
+
+tool_input = {
+ "comment_id": "comment-uuid-here",
+ "body": "Updated comment content in **Markdown** format."
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+)
+print(json.dumps(response.output.value, indent=2))
+
diff --git a/public/examples/integrations/mcp-servers/linear/update_initiative_example_call_tool.js b/public/examples/integrations/mcp-servers/linear/update_initiative_example_call_tool.js
new file mode 100644
index 000000000..229d6f4d1
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/update_initiative_example_call_tool.js
@@ -0,0 +1,31 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
+
+const USER_ID = "{arcade_user_id}"; // Unique identifier for your user (email, UUID, etc.)
+const TOOL_NAME = "Linear.UpdateInitiative";
+
+// Start the authorization process
+const authResponse = await client.tools.authorize({tool_name: TOOL_NAME, user_id: USER_ID});
+
+if (authResponse.status !== "completed") {
+ console.log(`Click this link to authorize: ${authResponse.url}`);
+}
+
+// Wait for the authorization to complete
+await client.auth.waitForCompletion(authResponse);
+
+const toolInput = {
+ "initiative_id": "initiative-uuid-here",
+ "name": "Q1 2025 Objectives - Updated",
+ "status": "started"
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
+
diff --git a/public/examples/integrations/mcp-servers/linear/update_initiative_example_call_tool.py b/public/examples/integrations/mcp-servers/linear/update_initiative_example_call_tool.py
new file mode 100644
index 000000000..ff599bc46
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/update_initiative_example_call_tool.py
@@ -0,0 +1,29 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
+
+USER_ID = "{arcade_user_id}" # Unique identifier for your user (email, UUID, etc.)
+TOOL_NAME = "Linear.UpdateInitiative"
+
+auth_response = client.tools.authorize(tool_name=TOOL_NAME, user_id=USER_ID)
+
+if auth_response.status != "completed":
+ print(f"Click this link to authorize: {auth_response.url}")
+
+# Wait for the authorization to complete
+client.auth.wait_for_completion(auth_response)
+
+tool_input = {
+ "initiative_id": "initiative-uuid-here",
+ "name": "Q1 2025 Objectives - Updated",
+ "status": "started"
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+)
+print(json.dumps(response.output.value, indent=2))
+
diff --git a/public/examples/integrations/mcp-servers/linear/update_issue_example_call_tool.js b/public/examples/integrations/mcp-servers/linear/update_issue_example_call_tool.js
new file mode 100644
index 000000000..a770a6ef5
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/update_issue_example_call_tool.js
@@ -0,0 +1,33 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
+
+const USER_ID = "{arcade_user_id}"; // Unique identifier for your user (email, UUID, etc.)
+const TOOL_NAME = "Linear.UpdateIssue";
+
+// Start the authorization process
+const authResponse = await client.tools.authorize({tool_name: TOOL_NAME, user_id: USER_ID});
+
+if (authResponse.status !== "completed") {
+ console.log(`Click this link to authorize: ${authResponse.url}`);
+}
+
+// Wait for the authorization to complete
+await client.auth.waitForCompletion(authResponse);
+
+const toolInput = {
+ "issue_id": "PROJ-123",
+ "title": "Updated title",
+ "priority": "urgent",
+ "labels_to_add": ["critical"],
+ "assignee": "john@example.com"
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
+
diff --git a/public/examples/integrations/mcp-servers/linear/update_issue_example_call_tool.py b/public/examples/integrations/mcp-servers/linear/update_issue_example_call_tool.py
new file mode 100644
index 000000000..ed610cf20
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/update_issue_example_call_tool.py
@@ -0,0 +1,31 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
+
+USER_ID = "{arcade_user_id}" # Unique identifier for your user (email, UUID, etc.)
+TOOL_NAME = "Linear.UpdateIssue"
+
+auth_response = client.tools.authorize(tool_name=TOOL_NAME, user_id=USER_ID)
+
+if auth_response.status != "completed":
+ print(f"Click this link to authorize: {auth_response.url}")
+
+# Wait for the authorization to complete
+client.auth.wait_for_completion(auth_response)
+
+tool_input = {
+ "issue_id": "PROJ-123",
+ "title": "Updated title",
+ "priority": "urgent",
+ "labels_to_add": ["critical"],
+ "assignee": "john@example.com"
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+)
+print(json.dumps(response.output.value, indent=2))
+
diff --git a/public/examples/integrations/mcp-servers/linear/update_project_example_call_tool.js b/public/examples/integrations/mcp-servers/linear/update_project_example_call_tool.js
new file mode 100644
index 000000000..6435ed5a2
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/update_project_example_call_tool.js
@@ -0,0 +1,32 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
+
+const USER_ID = "{arcade_user_id}"; // Unique identifier for your user (email, UUID, etc.)
+const TOOL_NAME = "Linear.UpdateProject";
+
+// Start the authorization process
+const authResponse = await client.tools.authorize({tool_name: TOOL_NAME, user_id: USER_ID});
+
+if (authResponse.status !== "completed") {
+ console.log(`Click this link to authorize: ${authResponse.url}`);
+}
+
+// Wait for the authorization to complete
+await client.auth.waitForCompletion(authResponse);
+
+const toolInput = {
+ "project_id": "project-uuid-here",
+ "name": "API Redesign v2",
+ "state": "started",
+ "lead": "john@example.com"
+};
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
+
diff --git a/public/examples/integrations/mcp-servers/linear/update_project_example_call_tool.py b/public/examples/integrations/mcp-servers/linear/update_project_example_call_tool.py
new file mode 100644
index 000000000..3100e3e84
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/update_project_example_call_tool.py
@@ -0,0 +1,30 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
+
+USER_ID = "{arcade_user_id}" # Unique identifier for your user (email, UUID, etc.)
+TOOL_NAME = "Linear.UpdateProject"
+
+auth_response = client.tools.authorize(tool_name=TOOL_NAME, user_id=USER_ID)
+
+if auth_response.status != "completed":
+ print(f"Click this link to authorize: {auth_response.url}")
+
+# Wait for the authorization to complete
+client.auth.wait_for_completion(auth_response)
+
+tool_input = {
+ "project_id": "project-uuid-here",
+ "name": "API Redesign v2",
+ "state": "started",
+ "lead": "john@example.com"
+}
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+)
+print(json.dumps(response.output.value, indent=2))
+
diff --git a/public/examples/integrations/mcp-servers/linear/who_am_i_example_call_tool.js b/public/examples/integrations/mcp-servers/linear/who_am_i_example_call_tool.js
new file mode 100644
index 000000000..2a79fc87a
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/who_am_i_example_call_tool.js
@@ -0,0 +1,27 @@
+import { Arcade } from "@arcadeai/arcadejs";
+
+const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
+
+const USER_ID = "{arcade_user_id}"; // Unique identifier for your user (email, UUID, etc.)
+const TOOL_NAME = "Linear.WhoAmI";
+
+// Start the authorization process
+const authResponse = await client.tools.authorize({tool_name: TOOL_NAME, user_id: USER_ID});
+
+if (authResponse.status !== "completed") {
+ console.log(`Click this link to authorize: ${authResponse.url}`);
+}
+
+// Wait for the authorization to complete
+await client.auth.waitForCompletion(authResponse);
+
+const toolInput = {}; // No parameters required
+
+const response = await client.tools.execute({
+ tool_name: TOOL_NAME,
+ input: toolInput,
+ user_id: USER_ID,
+});
+
+console.log(JSON.stringify(response.output.value, null, 2));
+
diff --git a/public/examples/integrations/mcp-servers/linear/who_am_i_example_call_tool.py b/public/examples/integrations/mcp-servers/linear/who_am_i_example_call_tool.py
new file mode 100644
index 000000000..a10bb3368
--- /dev/null
+++ b/public/examples/integrations/mcp-servers/linear/who_am_i_example_call_tool.py
@@ -0,0 +1,25 @@
+import json
+from arcadepy import Arcade
+
+client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
+
+USER_ID = "{arcade_user_id}" # Unique identifier for your user (email, UUID, etc.)
+TOOL_NAME = "Linear.WhoAmI"
+
+auth_response = client.tools.authorize(tool_name=TOOL_NAME, user_id=USER_ID)
+
+if auth_response.status != "completed":
+ print(f"Click this link to authorize: {auth_response.url}")
+
+# Wait for the authorization to complete
+client.auth.wait_for_completion(auth_response)
+
+tool_input = {} # No parameters required
+
+response = client.tools.execute(
+ tool_name=TOOL_NAME,
+ input=tool_input,
+ user_id=USER_ID,
+)
+print(json.dumps(response.output.value, indent=2))
+