/cyrus-setup-linear
Create a Linear OAuth application and configure Cyrus to use it — supports agent-browser automation or guided manual setup.
$ npx -y skills add cyrusagents/cyrus --skill cyrus-setup-linear --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/cyrus-setup-linear
Context preview
The summary Claude sees to decide when to auto-load this skill.
Create a Linear OAuth application and configure Cyrus to use it — supports agent-browser automation or guided manual setup.
SKILL.md
cyrus-setup-linear.SKILL.mdname: cyrus-setup-linear
description: Create a Linear OAuth application and configure Cyrus to use it — supports agent-browser automation or guided manual setup.
**CRITICAL: Never use `Read`, `Edit`, or `Write` tools on `~/.cyrus/.env` or any file inside `~/.cyrus/`. Use only `Bash` commands (`grep`, `printf >>`, etc.) to interact with env files — secrets must never be read into the conversation context. Never scrape, extract, or read secret values from web pages — guide the user to copy them manually.**
Setup Linear
Creates a Linear OAuth application and configures credentials so Cyrus can receive webhooks and respond to issues.
Step 1: Check Existing Configuration
grep -E '^LINEAR_CLIENT_ID=' ~/.cyrus/.env 2>/dev/null
If `LINEAR_CLIENT_ID` is already set, check if OAuth is also complete:
grep -q '"workspaces"' ~/.cyrus/config.json 2>/dev/null && echo "configured" || echo "not configured"
If both are set, inform the user:
> Linear is already configured. Skipping this step. > To reconfigure, remove `LINEAR_CLIENT_ID`, `LINEAR_CLIENT_SECRET`, and `LINEAR_WEBHOOK_SECRET` from `~/.cyrus/.env` and re-run.
Skip to completion.
Step 2: Get CYRUS_BASE_URL
Read the base URL from the env file (set by `setup-endpoint`):
grep '^CYRUS_BASE_URL=' ~/.cyrus/.env | cut -d= -f2-
This is needed for the callback and webhook URLs.
Step 3: Create Linear OAuth App From Manifest
Linear OAuth apps must be created from a manifest-backed setup URL. Do not create the app from scratch or fill each field manually. The manifest flow keeps the app configuration reproducible and avoids drift in callback, webhook, and event type settings.
3a. Build the manifest URL
Generate a JSON OAuth app manifest and encode it into Linear's `manifest` query parameter:
CYRUS_BASE_URL="<CYRUS_BASE_URL>" \
AGENT_NAME="<AGENT_NAME>" \
AGENT_DESCRIPTION="<AGENT_DESCRIPTION>" \
node <<'NODE'
const fs = require("node:fs");
const baseUrl = process.env.CYRUS_BASE_URL.replace(/\/+$/, "");
const agentName = process.env.AGENT_NAME || "Cyrus";
const agentDescription =
process.env.AGENT_DESCRIPTION || "AI coding agent for automated development";
const manifest = {
$schema: "https://linear.app/.well-known/oauth-app-manifest.schema.json",
schemaVersion: "1.0.0",
distribution: "private",
display: {
description: agentDescription,
},
developer: {
name: "Self-hosted",
},
oauth: {
client_name: agentName,
client_uri: "https://github.com/ceedaragents/cyrus",
redirect_uris: [`${baseUrl}/callback`],
grant_types: ["authorization_code"],
},
webhook: {
enabled: true,
url: `${baseUrl}/linear-webhook`,
resourceTypes: [
"AgentSessionEvent",
"AppUserNotification",
"PermissionChange",
"Issue",
],
},
};
const manifestJson = JSON.stringify(manifest, null, 2);
const manifestUrl = `https://linear.app/settings/api/applications/new?manifest=${encodeURIComponent(JSON.stringify(manifest))}`;
fs.writeFileSync("/tmp/cyrus-linear-oauth-app-manifest.json", `${manifestJson}\n`);
fs.writeFileSync("/tmp/cyrus-linear-oauth-app-url.txt", `${manifestUrl}\n`);
console.log(manifestJson);
console.log(`\n${manifestUrl}`);
NODE
LINEAR_MANIFEST_URL="$(cat /tmp/cyrus-linear-oauth-app-url.txt)"The same URL is now stored in `LINEAR_MANIFEST_URL` for automation commands and in `/tmp/cyrus-linear-oauth-app-url.txt` for manual copy/paste. The JSON is stored in `/tmp/cyrus-linear-oauth-app-manifest.json` for review/debugging only; do not ask the user to fill the OAuth app form manually from it.
If `<AGENT_NAME>` contains the word "Linear" or a URL, choose a different OAuth application name before building the manifest. Linear rejects OAuth client names with those values.
Determine which browser automation mode to use (see orchestrator rules):
1. If `claude-in-chrome` MCP tools are available → use **Path A-1** (claude-in-chrome) 2. If `agent-browser` is installed (`which agent-browser`) and a Chrome debug session is connected → use **Path A-2** (agent-browser) 3. Otherwise → use **Path B** (manual)
Path A-1: claude-in-chrome Automation
Use the `mcp__claude-in-chrome__*` tools to navigate and interact with the user's existing Chrome browser. The user is likely already signed in to Linear.
Navigate to `LINEAR_MANIFEST_URL`. The page should open with the manifest-applied OAuth app configuration already populated.
Review only non-secret fields:
- Application name matches `<AGENT_NAME>`
- Developer name is `Self-hosted`
- Developer URL is `https://github.com/ceedaragents/cyrus`
- Redirect callback URLs contains `<CYRUS_BASE_URL>/callback`
- Webhook is enabled with URL `<CYRUS_BASE_URL>/linear-webhook`
- Event types include Agent session events, Inbox notifications, Permission changes, and Issues
- Public/distribution is private or disabled
If the user is not signed in, pause and ask them to sign in. After review, click **Create**. **Do NOT screenshot credential pages or attempt to scrape secrets.** Proceed to Step 4.
Path A-2: agent-browser Automation
If `agent-browser` is connected to a Chrome debug session, automate the Linear app creation.
3b. Navigate to the manifest URL
agent-browser navigate "$LINEAR_MANIFEST_URL"
Wait for page to load. Take a screenshot to verify you're on the right page and logged in.
3c. Review and create
Review the same non-secret manifest-applied fields listed in Path A-1. If the page asks the user to sign in, pause and let them complete sign-in. Click **Create**.
After creation, Linear redirects to the app settings page. **Do NOT screenshot credential pages or attempt to scrape secrets.** Proceed to Step 4.
Path B: Manual Guided Setup
Guide the user through manual creation:
> ### Create a Linear OAuth Application > > 1. Open this manifest-backed Linear app creation URL: > > `<LINEAR_MANIFEST_URL>` > > 2. Sign in to Linear if prompted, then review the pre-filled settings: > - *
Read more
name: cyrus-setup-linear description: Create a Linear OAuth application and configure Cyrus to use it — supports agent-browser automation or guided manual setup.
**CRITICAL: Never use `Read`, `Edit`, or `Write` tools on `~/.cyrus/.env` or any file inside `~/.cyrus/`. Use only `Bash` commands (`grep`, `printf >>`, etc.) to interact with env files — secrets must never be read into the conversation context. Never scrape, extract, or read secret values from web pages — guide the user to copy them manually.**
Setup Linear
Creates a Linear OAuth application and configures credentials so Cyrus can receive webhooks and respond to issues.
Step 1: Check Existing Configuration
grep -E '^LINEAR_CLIENT_ID=' ~/.cyrus/.env 2>/dev/null
If `LINEAR_CLIENT_ID` is already set, check if OAuth is also complete:
grep -q '"workspaces"' ~/.cyrus/config.json 2>/dev/null && echo "configured" || echo "not configured"
If both are set, inform the user:
> Linear is already configured. Skipping this step. > To reconfigure, remove `LINEAR_CLIENT_ID`, `LINEAR_CLIENT_SECRET`, and `LINEAR_WEBHOOK_SECRET` from `~/.cyrus/.env` and re-run.
Skip to completion.
Step 2: Get CYRUS_BASE_URL
Read the base URL from the env file (set by `setup-endpoint`):
grep '^CYRUS_BASE_URL=' ~/.cyrus/.env | cut -d= -f2-
This is needed for the callback and webhook URLs.
Step 3: Create Linear OAuth App From Manifest
Linear OAuth apps must be created from a manifest-backed setup URL. Do not create the app from scratch or fill each field manually. The manifest flow keeps the app configuration reproducible and avoids drift in callback, webhook, and event type settings.
3a. Build the manifest URL
Generate a JSON OAuth app manifest and encode it into Linear's `manifest` query parameter:
CYRUS_BASE_URL="<CYRUS_BASE_URL>" \
AGENT_NAME="<AGENT_NAME>" \
AGENT_DESCRIPTION="<AGENT_DESCRIPTION>" \
node <<'NODE'
const fs = require("node:fs");
const baseUrl = process.env.CYRUS_BASE_URL.replace(/\/+$/, "");
const agentName = process.env.AGENT_NAME || "Cyrus";
const agentDescription =
process.env.AGENT_DESCRIPTION || "AI coding agent for automated development";
const manifest = {
$schema: "https://linear.app/.well-known/oauth-app-manifest.schema.json",
schemaVersion: "1.0.0",
distribution: "private",
display: {
description: agentDescription,
},
developer: {
name: "Self-hosted",
},
oauth: {
client_name: agentName,
client_uri: "https://github.com/ceedaragents/cyrus",
redirect_uris: [`${baseUrl}/callback`],
grant_types: ["authorization_code"],
},
webhook: {
enabled: true,
url: `${baseUrl}/linear-webhook`,
resourceTypes: [
"AgentSessionEvent",
"AppUserNotification",
"PermissionChange",
"Issue",
],
},
};
const manifestJson = JSON.stringify(manifest, null, 2);
const manifestUrl = `https://linear.app/settings/api/applications/new?manifest=${encodeURIComponent(JSON.stringify(manifest))}`;
fs.writeFileSync("/tmp/cyrus-linear-oauth-app-manifest.json", `${manifestJson}\n`);
fs.writeFileSync("/tmp/cyrus-linear-oauth-app-url.txt", `${manifestUrl}\n`);
console.log(manifestJson);
console.log(`\n${manifestUrl}`);
NODE
LINEAR_MANIFEST_URL="$(cat /tmp/cyrus-linear-oauth-app-url.txt)"The same URL is now stored in `LINEAR_MANIFEST_URL` for automation commands and in `/tmp/cyrus-linear-oauth-app-url.txt` for manual copy/paste. The JSON is stored in `/tmp/cyrus-linear-oauth-app-manifest.json` for review/debugging only; do not ask the user to fill the OAuth app form manually from it.
If `<AGENT_NAME>` contains the word "Linear" or a URL, choose a different OAuth application name before building the manifest. Linear rejects OAuth client names with those values.
Determine which browser automation mode to use (see orchestrator rules):
1. If `claude-in-chrome` MCP tools are available → use **Path A-1** (claude-in-chrome) 2. If `agent-browser` is installed (`which agent-browser`) and a Chrome debug session is connected → use **Path A-2** (agent-browser) 3. Otherwise → use **Path B** (manual)
Path A-1: claude-in-chrome Automation
Use the `mcp__claude-in-chrome__*` tools to navigate and interact with the user's existing Chrome browser. The user is likely already signed in to Linear.
Navigate to `LINEAR_MANIFEST_URL`. The page should open with the manifest-applied OAuth app configuration already populated.
Review only non-secret fields:
- Application name matches `<AGENT_NAME>`
- Developer name is `Self-hosted`
- Developer URL is `https://github.com/ceedaragents/cyrus`
- Redirect callback URLs contains `<CYRUS_BASE_URL>/callback`
- Webhook is enabled with URL `<CYRUS_BASE_URL>/linear-webhook`
- Event types include Agent session events, Inbox notifications, Permission changes, and Issues
- Public/distribution is private or disabled
If the user is not signed in, pause and ask them to sign in. After review, click **Create**. **Do NOT screenshot credential pages or attempt to scrape secrets.** Proceed to Step 4.
Path A-2: agent-browser Automation
If `agent-browser` is connected to a Chrome debug session, automate the Linear app creation.
3b. Navigate to the manifest URL
agent-browser navigate "$LINEAR_MANIFEST_URL"
Wait for page to load. Take a screenshot to verify you're on the right page and logged in.
3c. Review and create
Review the same non-secret manifest-applied fields listed in Path A-1. If the page asks the user to sign in, pause and let them complete sign-in. Click **Create**.
After creation, Linear redirects to the app settings page. **Do NOT screenshot credential pages or attempt to scrape secrets.** Proceed to Step 4.
Path B: Manual Guided Setup
Guide the user through manual creation:
> ### Create a Linear OAuth Application > > 1. Open this manifest-backed Linear app creation URL: > > `<LINEAR_MANIFEST_URL>` > > 2. Sign in to Linear if prompted, then review the pre-filled settings: > - *
Your (Claude Code|Codex|Cursor|Gemini) powered (Linear|GitHub|GitLab|Slack) agent.
Repo: cyrusagents/cyrus
Other skills on cyrus.
- /google
Search the web for information. Use when you need to look something up, find current information, or research a topic.
Open skill - /release-core-test
Invoke when dev-testing a Cyrus change that spans CYPACK (edgeworker + CLI) and CYHOST (Vercel-hosted GUI) and the hosted GUI needs to point at an unreleased `cyrus-core` from this repo. Publishes `cyrus-core` (and `claude-runner` if needed) as a `-test.N` prerelease under the
Open skill - /cyrus-setup-claude-auth
Configure Claude Code authentication for Cyrus — API key, OAuth token, or third-party provider.
Open skill - /cyrus-setup-endpoint
Configure the public webhook endpoint for Cyrus — ngrok, Cloudflare Tunnel, or custom URL.
Open skill - /cyrus-setup-github
Configure GitHub for Cyrus — gh CLI login and git config for PRs, with optional webhook setup to enable @mention responses in PR comments, automated rebases and merges, and auto-fixing based on CI failures (coming soon).
Open skill - /cyrus-setup-gitlab
Configure GitLab authentication for Cyrus — glab CLI login and git config for creating merge requests.
Open skill

