Announcing CIMD support for MCP Client registration
Learn more

Linear MCP server: set up Claude Code, Cursor, Codex and your agent

Diagram: Claude Code, Cursor and Codex connect to Linear's MCP server at mcp.linear.app/mcp, and a product's agent reaches it through Scalekit with a session token per user.
Nityashree Yadunath
Product Marketing Manager

The Linear MCP server is Linear's official hosted server at https://mcp.linear.app/mcp. It uses Streamable HTTP, signs you in with OAuth 2.1, and acts as the Linear user who authorized it, so every issue it creates and every comment it posts is attributed to you. Claude Code connects with one claude mcp add command and a /mcp sign-in.

That covers one person in one editor. Cursor and Codex take one step each, and the official server also accepts an API key for headless runs. If you are building an agent that works in many of your users' Linear workspaces, the work moves to your back end, which has to hold one authorization per user. That requirement applies to most MCP integrations in multi-user products.

TL;DR

  • Linear runs one official remote server with two endpoints: /mcp (read and write) and /mcp/readonly (read tools only). You sign in with OAuth 2.1, or send a Linear API key or OAuth token as a bearer header.
  • Claude Code, Cursor and Codex each connect with one command or one config entry. Keep agents read-only by default with the read-only URL, the read OAuth scope or a Read-only API key, and require approval for writes.
  • For a product whose agent acts for many users, your back end becomes the OAuth client and must store, refresh and revoke each user's Linear tokens. Scalekit AgentKit does that and gives your agent one server URL plus a short-lived session token per user.

What Linear's official MCP server is

Linear launched its hosted MCP server in May 2025 and runs it centrally. Its MCP documentation describes tools for finding, creating and updating issues, projects and comments, with more added over time. Scalekit's Linear MCP connector, which passes calls through to this server, lists 63 tools today: 37 read, 14 write and 12 destructive, covering issues, projects, milestones, initiatives, documents, comments, customers, releases and code review threads.

The server has two endpoints under https://mcp.linear.app:

Endpoint
Transport
Access
Use it when
/mcp
Streamable HTTP
Read and write (default)
Most setups
/mcp/readonly
Streamable HTTP
Read tools only
Summaries, reports and agents that should never change data

How it authenticates

The default flow is interactive OAuth 2.1 with dynamic client registration. The server's published OAuth metadata, at /.well-known/oauth-authorization-server, advertises the read and write scopes, the authorization code grant with PKCE (S256), refresh tokens, a dynamic client registration endpoint and support for Client ID Metadata Documents. A request without a token gets a 401 whose WWW-Authenticate header points to the server's protected resource metadata, which names that authorization server. That is how MCP clients find the sign-in flow without extra configuration.

Linear also accepts an OAuth access token or a Linear API key in an Authorization: Bearer header, skipping the browser step. Linear lists three uses: acting as an app user, giving read-only access through a restricted API key, and reusing an existing Linear OAuth application. You create API keys under Settings > Account > Security & Access; a key with only the Read permission gives read-only access on the standard endpoint.

Workspaces on Okta can turn on enterprise-managed authorization: configure SAML for Linear through Okta's OIN, enable MCP enterprise managed authentication in Linear's Okta identity provider settings, and paste the Okta authorization server's issuer URI. Supported clients such as Claude then sign users in under the organization's Okta access policies.

Add the Linear MCP server to Claude Code

claude mcp add --transport http linear-server https://mcp.linear.app/mcp

Open a session, run /mcp, pick linear-server and finish the sign-in in your browser. You can also sign in from the shell with claude mcp login linear-server. The server is added at local scope, for you in the current project; add --scope user to use it in every project, or --scope project to write it to a shared .mcp.json. Claude Code stores and refreshes the OAuth tokens, and claude mcp logout linear-server clears them. The Claude Code MCP docs cover every flag.

To keep Claude read-only, either point the entry at https://mcp.linear.app/mcp/readonly or pin the OAuth scope in .mcp.json. Linear grants read-only access to clients that request only read, and the resulting token cannot reach write APIs.

{ "mcpServers": { "linear-server": { "type": "http", "url": "https://mcp.linear.app/mcp", "oauth": { "scopes": "read" } } } }

A claude -p run or an Agent SDK session has no /mcp panel, so it cannot complete an OAuth sign-in. Either sign in once from an interactive session, or send an API key. Claude Code expands environment variables in a server's url and headers, so the key stays out of the file:

{ "mcpServers": { "linear-server": { "type": "http", "url": "https://mcp.linear.app/mcp", "headers": { "Authorization": "Bearer ${LINEAR_API_KEY}" } } } }

Add it to Cursor

Linear's docs link a one-click install for Cursor, and Linear is listed in Cursor's marketplace. To add it by hand, put this in ~/.cursor/mcp.json for every project or .cursor/mcp.json for one project:

{ "mcpServers": { "linear": { "url": "https://mcp.linear.app/mcp" } } }

Cursor runs the OAuth sign-in when the server asks for it. To use an API key instead, add a headers object to the entry with Authorization set to Bearer ${env:LINEAR_API_KEY}; Cursor resolves ${env:NAME} in url and headers. By default Cursor asks for approval before it uses an MCP tool, and shows the arguments it is about to send (see Cursor MCP docs).

Add it to Codex

codex mcp add linear --url https://mcp.linear.app/mcp codex mcp login linear

The Codex CLI, the IDE extension and the ChatGPT desktop app share one MCP configuration, so you set it up once. Linear's docs say the add command prompts you to sign in; codex mcp login linear runs the sign-in again whenever you need it. The same server in ~/.codex/config.toml, with approval required for any tool the server does not mark read-only:

[mcp_servers.linear] url = "https://mcp.linear.app/mcp" default_tools_approval_mode = "writes"

For an API key, add bearer_token_env_var = "LINEAR_API_KEY" to the table, and Codex sends the variable's value as the bearer token. Linear's setup page also adds experimental_use_rmcp_client = true under [features], a flag that older Codex releases needed for remote servers. Current releases support Streamable HTTP servers with OAuth without it, as the Codex MCP docs describe, and ignore the key, so you can leave it out.

VS Code, Windsurf, Zed and other clients

Linear's instructions for VS Code, Windsurf and Zed use the mcp-remote bridge, and the same settings work in any client that only runs local servers: command npx, arguments -y mcp-remote https://mcp.linear.app/mcp, no environment variables. The bridge runs on your machine, handles the OAuth flow and keeps its credentials in ~/.mcp-auth. Linear's FAQ suggests deleting that folder if you see an internal server error, and updating Node.js if needed.

Each Linear workspace needs its own authorization, and reconnecting does not switch workspaces inside an existing session. With mcp-remote, give each workspace its own directory and sign in to each one separately:

MCP_REMOTE_CONFIG_DIR=~/.mcp-auth/workspace-a npx mcp-remote https://mcp.linear.app/mcp MCP_REMOTE_CONFIG_DIR=~/.mcp-auth/workspace-b npx mcp-remote https://mcp.linear.app/mcp

Official, self-hosted or managed: which to use

Option
Runs on
Credential
Better fit when
Linear's official server
Linear's infrastructure
Your own OAuth sign-in, or a Linear API key or OAuth token as a bearer header
You, or each person on your team, use Linear from Claude Code, Cursor, Codex or Claude
Self-hosted community server
Your machine, over stdio
A personal API key in an environment variable
You want to read, change or extend the server's code and tool set yourself
Managed per-user server
The vendor's infrastructure
Each end user's Linear tokens, stored and refreshed by the vendor
Your product's agent acts in many users' Linear workspaces

The official server is the right default for anyone using Linear from their own editor. Linear maintains the tools, and you only manage a sign-in.

Self-hosted servers are open source and run with whatever key you give them. An early community server, jerhadf/linear-mcp-server, now says in its README that it is deprecated and points users to Linear's official server. tacticlaunch/mcp-linear is MIT-licensed, still maintained, runs with npx -y @tacticlaunch/mcp-linear and a LINEAR_API_TOKEN, and its README lists tools for workspace webhooks, templates and custom fields. Treat any third-party server like other code you run with a credential, and vet it before you install it.

Managed services hold one authorization per end user. Composio lists 47 Linear tools and 12 triggers, supports OAuth and API keys, and creates an MCP session per user ID. It is the better fit when you want Linear event triggers from the same platform that runs the tools, or you already build on Composio sessions.

Connect your own agent for many users

Linear's server trusts whoever completed the sign-in, and the client keeps the tokens. In Claude Code, that client is a developer's laptop. When your product's agent works in your customers' Linear workspaces, your back end is the client, and for every user it has to:

  1. Register with Linear's authorization server, through dynamic client registration or a Client ID Metadata Document.
  2. Run the authorization code flow with PKCE when the user connects Linear.
  3. Store the access and refresh tokens encrypted, keyed by your own user ID rather than an email address.
  4. Refresh tokens before they expire, and notice when a refresh fails so the user can reconnect.
  5. Attach the right user's token to each call, and never let one user's run use another user's token.
  6. Delete the tokens when the user disconnects.

Per-user OAuth for MCP integrations covers this design and how it fails, and token refresh for third-party MCP servers covers the refresh step. If your agent needs webhooks or arbitrary GraphQL queries rather than fixed tools, Linear MCP vs Linear API compares the two surfaces.

With Scalekit AgentKit

AgentKit is an MCP gateway that runs each user's OAuth flow, stores their tokens encrypted with AES-256-GCM under a key per environment, refreshes them and calls tools as that user. It has two Linear connectors, and both can use Scalekit's OAuth app or your own:

  • Linear MCP routes calls to Linear's own MCP server and lists 63 tools. Users sign in with OAuth 2.1 through dynamic client registration.
  • Linear is Scalekit's connector over Linear's API, with 62 tools, including linear_graphql_query and webhook management. Users sign in with OAuth 2.0.

You create a Virtual MCP server once per agent role and choose its tools. All users share its URL. Before each run, your back end mints a session token for one user, and the agent connects with that token. Scalekit checks the token, finds that user's Linear account and calls Linear with it; your agent never receives the user's Linear token.

Once per agent role: create the server.

import os from scalekit import ScalekitClient from scalekit.actions.models.mcp_config import McpConfigConnectionToolMapping actions = ScalekitClient( env_url=os.environ["SCALEKIT_ENVIRONMENT_URL"], client_id=os.environ["SCALEKIT_CLIENT_ID"], client_secret=os.environ["SCALEKIT_CLIENT_SECRET"], ).actions server = actions.mcp.create_config( name="linear-triage", connection_tool_mappings=[ McpConfigConnectionToolMapping( connection_name="linearmcp", # your Linear MCP connection tools=[ "linearmcp_list_issues", "linearmcp_get_issue", "linearmcp_list_comments", "linearmcp_save_comment", ], ) ], ).config print(server.id, server.mcp_server_url)

Before each run: check the user's account, then mint a token.

from datetime import timedelta user_id = "user_123" # your app's stable ID for this user accounts = actions.mcp.list_mcp_connected_accounts( config_id=server.id, identifier=user_id, include_auth_link=True ) for account in accounts.connected_accounts: if account.connected_account_status != "ACTIVE": print("Send the user this link:", account.authentication_link) session = actions.mcp.create_session_token( mcp_config_id=server.id, identifier=user_id, expiry=timedelta(minutes=30), )

During the run: connect any MCP client with the server URL and the session token as a bearer header. With the Python MCP SDK (version 2):

import asyncio import httpx2 from mcp import Client from mcp.client.streamable_http import streamable_http_client async def run(): headers = {"Authorization": f"Bearer {session.token}"} async with httpx2.AsyncClient(headers=headers, timeout=30) as http: transport = streamable_http_client(server.mcp_server_url, http_client=http) async with Client(transport) as mcp: tools = await mcp.list_tools() print([tool.name for tool in tools.tools]) result = await mcp.call_tool( "linearmcp_list_issues", {"assignee": "me"} ) print(result.is_error, result.content) asyncio.run(run())

How session tokens behave:

  • A token is bound to one user and one server. Sent to any other server URL, it returns 401.
  • It lasts one hour by default, and you can set anything from 60 seconds to 24 hours.
  • It is short-lived by design and is not refreshed. Mint a new one per run, per chat session, or on a schedule for a long-running host. Minting a new token does not revoke earlier ones.
  • Add access_level="READ_ONLY" and the run sees only the server's read-only tools; a call to any other tool is refused before it reaches Linear.

By default, the tools/list response also includes a connect_account tool, so an agent can fetch an authorization link for a user who has not connected Linear yet. To revoke one user, delete their connected account; their next call fails until they authorize again, and other users keep working:

actions.delete_connected_account( connection_name="linearmcp", identifier=user_id )

For an agent that only needs one app, every connection also has its own MCP server with all of its tools at <environment URL>/mcp/v3/connections/linearmcp; mint the token with connection_name="linearmcp" instead of a server ID.

Use the same server from Claude Code while you build

Session tokens expire, so a static header in a config file stops working within a day. Claude Code's headersHelper runs a command at each connection, uses the JSON it prints as request headers, and runs it again when a tool call returns 401 or 403. A helper that mints a fresh token for a test user:

# mint_header.py import json import os from datetime import timedelta from scalekit import ScalekitClient actions = ScalekitClient( env_url=os.environ["SCALEKIT_ENVIRONMENT_URL"], client_id=os.environ["SCALEKIT_CLIENT_ID"], client_secret=os.environ["SCALEKIT_CLIENT_SECRET"], ).actions session = actions.mcp.create_session_token( mcp_config_id=os.environ["LINEAR_MCP_CONFIG_ID"], identifier=os.environ["APP_USER_ID"], expiry=timedelta(hours=8), ) print(json.dumps({"Authorization": f"Bearer {session.token}"}))
claude mcp add-json linear-agent --scope user \ '{"type":"http","url":"YOUR_MCP_SERVER_URL","headersHelper":"python3 /absolute/path/to/mint_header.py"}'

Use user or local scope for this entry. Claude Code runs helpers from a project .mcp.json without environment variables whose names look like credentials, so a shared project file would not see your Scalekit secret. Codex has a similar option, http_headers_helper.

Security notes

  • Start read-only. Use /mcp/readonly, the read scope or a Read-only API key with Linear's server, or a read-only session token with Scalekit. Agents read issue descriptions and comments written by other people, and an instruction hidden in one of them cannot trigger a write if the agent has no write tools.
  • Require a person for writes. Cursor asks before each MCP tool call by default. In Codex, default_tools_approval_mode = "writes" prompts for any tool not marked read-only. In Claude Code, an ask rule such as mcp__linear-server__* in /permissions makes every Linear call wait for you. Linear's save tools both create and update records. Scalekit's connector reference marks linearmcp_save_issue and linearmcp_save_comment as destructive, so a read-only session token leaves them out.
  • Keep API keys out of files. A personal Linear API key belongs to your account. Reference it through an environment variable, as in the examples above, and never commit it to a shared .mcp.json.
  • Know how to revoke. In Linear, Settings > Account > Security & Access lists your authorized applications with a Revoke access option and your personal API keys (Linear security docs). In Claude Code, claude mcp logout clears stored tokens. With Scalekit, deleting a connected account removes one user's access without touching anyone else's.
  • Give each agent the tools it needs. A triage agent that reads issues and adds comments does not need delete tools. A Virtual MCP server exposes only the tools you list, which also keeps the tool list in the model's context short.

FAQs

What is the Linear MCP server?

It is Linear's official, centrally hosted MCP server at https://mcp.linear.app/mcp. It uses Streamable HTTP and OAuth 2.1, and its tools find, create and update issues, projects, comments and other Linear objects as the user who signed in.

How do I add Linear MCP to Claude Code?

Run claude mcp add --transport http linear-server https://mcp.linear.app/mcp, start a session and run /mcp to sign in with your Linear account. Add --scope user to make it available in every project.

Is there a read-only Linear MCP server?

Yes. Connect to https://mcp.linear.app/mcp/readonly, which only exposes read tools, or request only the read OAuth scope on the standard endpoint. A Linear API key with only the Read permission also gives read-only access.

Can I use a Linear API key instead of OAuth?

Yes. Linear's MCP server accepts a Linear API key or an OAuth access token in an Authorization: Bearer header. This suits headless runs, app users and restricted read-only keys.

Can I connect more than one Linear workspace?

Yes, but each workspace needs its own authorization, because reconnecting does not switch workspaces within a session. With the mcp-remote bridge, give each workspace its own MCP_REMOTE_CONFIG_DIR and sign in to each one separately.

How do I let my own agent use Linear for many users?

Each user has to authorize Linear once, and your back end has to store, refresh and revoke their tokens. With Scalekit AgentKit, users connect through the Linear MCP connector, and each run gets a short-lived session token for one user on a shared Virtual MCP server URL.

Does Linear's MCP server support SSE clients?

Connect over Streamable HTTP at https://mcp.linear.app/mcp, which is the endpoint Linear recommends for every setup. If your client only runs local servers, use the mcp-remote bridge with that /mcp URL.

Details checked October 2026.

No items found.
Agent
Auth Quickstart
On this page
Share this article
Agent
Auth Quickstart

Acquire enterprise customers with
‍zero upfront cost.

Every feature unlocked. No hidden fees.