Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 122 additions & 30 deletions app/en/home/auth-providers/linear/page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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.

<Callout>
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!
</Callout>

### 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

Expand All @@ -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



<Tabs items={["Dashboard GUI"]}>
<Tabs.Tab>

Expand All @@ -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

Expand All @@ -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:

<Tabs items={["Python", "JavaScript"]} storageKey="preferredLanguage">
<Tabs.Tab>

```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":
Expand All @@ -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)
```

</Tabs.Tab>

<Tabs.Tab>

```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"],
Expand All @@ -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);
```

</Tabs.Tab>
Expand All @@ -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
Expand All @@ -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 = """
Expand All @@ -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
```
Loading