Skip to content

Commit b5d19cb

Browse files
jottakkaFrancisco Liberal
andauthored
[TOO-177] Linear arcade evals doc updates (#581)
* updating issues * updating tool * update docs --------- Co-authored-by: Francisco Liberal <francisco@arcade.dev>
1 parent ba7c934 commit b5d19cb

File tree

77 files changed

+3890
-69
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+3890
-69
lines changed

app/en/home/auth-providers/linear/page.mdx

Lines changed: 122 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,20 @@ import { Tabs, Callout, Steps } from "nextra/components";
44

55
The Linear auth provider enables tools and agents to call [Linear APIs](https://linear.app/developers/graphql) on behalf of a user.
66

7+
<Callout>
8+
Want to quickly get started with Linear in your agent or AI app? The pre-built
9+
[Arcade Linear MCP Server](/mcp-servers/productivity/linear) is what you want!
10+
</Callout>
11+
712
### What's documented here
813

914
This page describes how to use and configure Linear auth with Arcade.
1015

1116
This auth provider is used by:
1217

13-
- Your [app code](#using-linear-auth-in-app-code) that needs to call the Linear API
14-
- Or, your [custom tools](#using-Linear-auth-in-custom-tools) that need to call the Linear API
18+
- The [Arcade Linear MCP Server](/mcp-servers/productivity/linear), which provides pre-built tools for interacting with Linear
19+
- Your [app code](#using-linear-auth-in-app-code) that needs to call Linear APIs
20+
- Or, your [custom tools](#using-linear-auth-in-custom-tools) that need to call Linear APIs
1521

1622
## Configuring Linear auth
1723

@@ -25,24 +31,22 @@ This auth provider is used by:
2531

2632
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.
2733

28-
2934
Before showing how to configure your Linear app credentials, let's go through the steps to create a Linear app.
3035

3136
### Create a Linear app
3237

33-
- It is **highly recommended** to first [create a new Linear workspace](https://linear.app/join) for the purpose of managing the OAuth2 Application.
34-
- Create a new public OAuth2 Application in your [integration's settings page](https://linear.app/settings/api/applications/new).
35-
- Fill out your application specific information such as application name and description.
36-
- Set the Callback URL to the redirect URL generated by Arcade (see below)
37-
- Toggle the **Public** switch to enable public access to the application if you want other workspaces to be able to use your application.
38-
- Once you complete creating your integration, copy the client ID and client secret to use below.
38+
- 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
39+
- Create a new public OAuth2 Application in your [integration settings page](https://linear.app/settings/api/applications/new)
40+
- Fill out your application specific information such as application name and description
41+
- Choose the [scopes](https://linear.app/developers/oauth-2-0-authentication#redirect-user-access-requests-to-linear) (permissions) you need for your app
42+
- Add the redirect URL generated by Arcade (see below) to the Callback URL field
43+
- Toggle the **Public** switch if you want other workspaces to be able to use your application
44+
- Copy the client ID and client secret to use below
3945

4046
Next, add the Linear app to Arcade.
4147

4248
## Configuring your own Linear Auth Provider in Arcade
4349

44-
45-
4650
<Tabs items={["Dashboard GUI"]}>
4751
<Tabs.Tab>
4852

@@ -66,7 +70,7 @@ To access the Arcade Cloud dashboard, go to [api.arcade.dev/dashboard](https://a
6670
- Choose a unique **ID** for your provider (e.g. "my-linear-provider").
6771
- Optionally enter a **Description**.
6872
- Enter the **Client ID** and **Client Secret** from your Linear app.
69-
- Note the **Redirect URL** generated by Arcade. This must be set as your Linear app's Callback URL.
73+
- Note the **Redirect URL** generated by Arcade. This must be added to your Linear app's Callback URL field.
7074

7175
#### Create the provider
7276

@@ -81,27 +85,38 @@ When you use tools that require Linear auth using your Arcade account credential
8185

8286
## Using Linear auth in app code
8387

84-
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.
88+
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.
8589

86-
Use `client.auth.start()` to get a user token for the Linear API:
90+
Use `client.auth.start()` to get a user token for Linear APIs:
8791

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

91-
```python {8-14}
95+
```python {22-26}
9296
from arcadepy import Arcade
97+
import httpx
9398

9499
client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
95100

96101
user_id = "{arcade_user_id}"
97102

103+
"""
104+
In this example, we will use Arcade to authenticate with Linear and
105+
retrieve teams.
106+
107+
There is a tool for that in the Arcade Linear MCP Server, which simplifies
108+
the process for you to interact with Linear either through our Python or
109+
JavaScript SDKs or via LLM tool calling.
110+
111+
Below we are just showing how to use Arcade as an auth provider, if you ever
112+
need to.
113+
"""
114+
98115
# Start the authorization process
99116
auth_response = client.auth.start(
100117
user_id=user_id,
101118
provider="linear",
102-
scopes=[
103-
"read"
104-
],
119+
scopes=["read"],
105120
)
106121

107122
if auth_response.status != "completed":
@@ -112,20 +127,59 @@ if auth_response.status != "completed":
112127
auth_response = client.auth.wait_for_completion(auth_response)
113128

114129
token = auth_response.context.token
115-
# Do something interesting with the token...
130+
131+
if not token:
132+
raise ValueError("No token found in auth response")
133+
134+
# Use the Linear GraphQL API
135+
url = "https://api.linear.app/graphql"
136+
headers = {
137+
"Authorization": f"Bearer {token}",
138+
"Content-Type": "application/json",
139+
}
140+
141+
query = """
142+
query Teams {
143+
teams {
144+
nodes {
145+
id
146+
name
147+
key
148+
}
149+
}
150+
}
151+
"""
152+
153+
response = httpx.post(url, json={"query": query}, headers=headers)
154+
data = response.json()
155+
teams = data["data"]["teams"]["nodes"]
156+
157+
print(teams)
116158
```
117159

118160
</Tabs.Tab>
119161

120162
<Tabs.Tab>
121163

122-
```javascript {8-10}
164+
```javascript {20-22}
123165
import { Arcade } from "@arcadeai/arcadejs";
124166

125167
const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
126168

127169
const userId = "{arcade_user_id}";
128170

171+
/*
172+
In this example, we will use Arcade to authenticate with Linear and
173+
retrieve teams.
174+
175+
There is a tool for that in the Arcade Linear MCP Server, which simplifies
176+
the process for you to interact with Linear either through our Python or
177+
JavaScript SDKs or via LLM tool calling.
178+
179+
Below we are just showing how to use Arcade as an auth provider, if you ever
180+
need to.
181+
*/
182+
129183
// Start the authorization process
130184
let authResponse = await client.auth.start(userId, "linear", {
131185
scopes: ["read"],
@@ -139,8 +193,42 @@ if (authResponse.status !== "completed") {
139193
// Wait for the authorization to complete
140194
authResponse = await client.auth.waitForCompletion(authResponse);
141195

196+
if (!authResponse.context.token) {
197+
throw new Error("No token found in auth response");
198+
}
199+
142200
const token = authResponse.context.token;
143-
// Do something interesting with the token...
201+
202+
// Use the Linear GraphQL API
203+
const response = await fetch("https://api.linear.app/graphql", {
204+
method: "POST",
205+
headers: {
206+
Authorization: `Bearer ${token}`,
207+
"Content-Type": "application/json",
208+
},
209+
body: JSON.stringify({
210+
query: `
211+
query Teams {
212+
teams {
213+
nodes {
214+
id
215+
name
216+
key
217+
}
218+
}
219+
}
220+
`,
221+
}),
222+
});
223+
224+
if (!response.ok) {
225+
throw new Error(`HTTP error! status: ${response.status}`);
226+
}
227+
228+
const data = await response.json();
229+
const teams = data.data.teams.nodes;
230+
231+
console.log(teams);
144232
```
145233

146234
</Tabs.Tab>
@@ -155,7 +243,7 @@ If the pre-built tools in the Linear MCP Server don't meet your needs, you can a
155243

156244
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:
157245

158-
```python
246+
```python {3-4,10-14,26}
159247
from typing import Annotated, Any
160248

161249
from arcade_tdk import ToolContext, tool
@@ -165,14 +253,18 @@ import httpx
165253

166254

167255
@tool(requires_auth=Linear(scopes=["read"]))
168-
async def get_teams(context: ToolContext) -> Annotated[dict[str, Any], "Teams in the workspace with member information"]:
256+
async def get_teams(
257+
context: ToolContext,
258+
) -> Annotated[dict[str, Any], "Teams in the workspace with member information"]:
169259
"""Get Linear teams and team information including team members"""
170-
token = context.get_auth_token_or_empty()
260+
if not context.authorization or not context.authorization.token:
261+
raise ValueError("No token found in context")
262+
263+
token = context.authorization.token
171264
url = "https://api.linear.app/graphql"
172265
headers = {
173266
"Authorization": f"Bearer {token}",
174267
"Content-Type": "application/json",
175-
"Accept": "application/json",
176268
}
177269

178270
query = """
@@ -188,9 +280,9 @@ async def get_teams(context: ToolContext) -> Annotated[dict[str, Any], "Teams in
188280
"""
189281

190282
async with httpx.AsyncClient() as client:
191-
resp = await client.post(url, json={"query": query}, headers=headers)
192-
resp.raise_for_status()
193-
data = resp.json()
194-
teams = data["data"]["teams"]["nodes"]
195-
return teams
283+
resp = await client.post(url, json={"query": query}, headers=headers)
284+
resp.raise_for_status()
285+
data = resp.json()
286+
teams = data["data"]["teams"]["nodes"]
287+
return teams
196288
```

0 commit comments

Comments
 (0)