A Monday sprint digest
Every Monday at 9:00, list every Linear issue assigned to me that is still open, group them by project, and write me a short plan for the week naming the three I should finish first.
Verified MCP server: Linear
The tool list below is a live capture from the running server; an authenticated tool call is still pending credentials.
The short answer
Last verified 2026-08-03
The Linear MCP server exists in two shapes, and this page checks both. Linear ships an official one itself: a hosted server at https://mcp.linear.app/mcp that your AI app connects to over HTTP. We called it with no credentials and it answered with a 401 telling us to log in through OAuth, which is printed further down, so there was no honest way to list its tools without signing a real workspace in. To give you a live tool list anyway, we ran the most downloaded community package instead, @tacticlaunch/mcp-linear, which wraps the same Linear API as a local stdio server: it started, enumerated 198 tools, and returned a real authentication error for the one tool call we made with a placeholder token. Every tool name and description below is that capture, word for word. What we did not do is authenticate, so no issue in anyone's Linear was read, created, or changed. [1][3][6]
Verification
Method
We started the server with npx over stdio twice. With no credential at all it refuses to boot and prints the banner below, which names the environment variables it accepts. With a placeholder token it boots silently, completed the MCP initialize handshake, and answered tools/list with the 198 tools listed on this page, word for word. We then made one real tools/call, linear_getViewer, and Linear rejected it: the excerpt below is that reply, verbatim. Authenticated calls are pending a credential we do not have, namely a Linear API key from a real Linear workspace, so nothing here claims a successful authenticated call. Separately we sent an unauthenticated initialize to Linear's own hosted endpoint at https://mcp.linear.app/mcp and recorded its 401, which is in the troubleshooting section below.
Startup banner
API token not found in command line args or environment variables Error starting MCP Linear Error: Linear credentials not found. Provide an API token via --token, LINEAR_API_TOKEN, or LINEAR_API_KEY, or sign in with `mcp-linear auth login`.
One real tool call
tools/call linear_getViewer {}Error: Authentication required, not authenticated - You need to authenticate to access this operation.
Real lines from the captured result: enough to prove the call answered.
Tools
The server answered tools/list with 198 tools on 2026-08-03. The names, descriptions and parameters below are its own words, copied from that response and never edited.
| Tool | What it does |
|---|---|
| linear_getViewer | Get information about the currently authenticated user |
| linear_getOrganization | Get information about the current Linear organization |
| linear_getUsers | Get a list of users in the Linear organization |
| linear_getLabels | Get a list of issue labels from Linear |
| linear_getTeams | Get a list of teams from Linear |
| linear_getWorkflowStatesteamId*includeArchived | Get workflow states for a team |
| linear_createWorkflowStatename*teamId*type*color*descriptionposition | Create a new workflow state |
| linear_updateWorkflowStateid*namecolordescriptionposition | Update a workflow state. Provide id plus at least one other field to change. |
| linear_updateTeamid*namekeydescriptioncoloricontimezoneparentIdprivatevisibility | Update team settings |
| linear_getTeamMembershipsteamId*limitincludeArchivedorderBy | Get team memberships |
| linear_createTeamname*keydescriptioncoloricontimezoneparentIdprivatevisibility | Create a new team |
| linear_archiveTeamid* | Archive a team |
| linear_addUserToTeamteamId*userId*ownersortOrder | Add a user to a team |
| linear_removeUserFromTeamteamId*userId*alsoLeaveParentTeams | Remove a user from a team |
| linear_updateTeamMembershipid*ownersortOrder | Update a user's role in a team. Provide id plus at least one other field to change. |
| linear_getTeamLabelsteamId*limitincludeArchivedorderBy | Get labels for a specific team |
| linear_createTeamLabelteamId*name*colordescriptionparentId | Create a new label for a team |
| linear_getProjects | Get a list of projects from Linear |
| linear_getProjectByIdid* | Get details for a specific Linear project by ID |
| linear_createProjectname*descriptioncontentteamIds*statestartDatetargetDateleadIdmemberIdssortOrdericoncolor | Create a new project in Linear |
| linear_updateProjectid*namedescriptioncontentstatestartDatetargetDateleadIdmemberIdssortOrdericoncolor | Update an existing project in Linear |
| linear_createProjectUpdateprojectId*body*healthisDiffHidden | Create a new project update for a Linear project |
| linear_updateProjectUpdateid*bodyhealthisDiffHidden | Update an existing project update in Linear |
| linear_getProjectUpdateByIdid* | Get a specific Linear project update by ID |
| linear_getProjectUpdatesprojectId*limit | Get all updates associated with a project |
| linear_archiveProjectUpdateid* | Archive a Linear project update |
| linear_unarchiveProjectUpdateid* | Restore an archived Linear project update |
| linear_deleteProjectUpdateid* | Delete a Linear project update |
| linear_archiveProjectprojectId* | Archive a project |
| linear_addIssueToProjectissueId*projectId* | Add an existing issue to a project |
| linear_removeIssueFromProjectissueId*projectId* | Remove an existing issue from a project |
| linear_getProjectIssuesprojectId*limitstatesassigneeIdlabelIdscycleIdprojectMilestoneIdincludeCompletedorderBy | Get issues associated with a project, with PM-friendly filters like state, assignee, labels, cycle, and milestone |
| linear_getProjectMembersprojectId*limitincludeArchivedincludeDisabledorderBy | Get members assigned to a project |
| linear_addProjectMemberprojectId*userId* | Add a member to a project |
| linear_removeProjectMemberprojectId*userId* | Remove a member from a project |
| linear_getRoadmapslimitincludeArchivedorderBy | Get a list of roadmaps from Linear |
| linear_getRoadmapByIdid* | Get details of a specific roadmap by ID |
| linear_createRoadmapname*descriptioncolorownerIdsortOrder | Create a new roadmap in Linear |
| linear_updateRoadmapid*namedescriptioncolorownerIdsortOrder | Update an existing roadmap |
| linear_archiveRoadmaproadmapId* | Archive a roadmap |
| linear_getReleasePipelineslimitincludeArchivedorderBy | Get release pipelines from Linear |
| linear_getReleasePipelineByIdid* | Get details of a specific release pipeline |
| linear_createReleasePipelinename*teamIds*typeslugIdisProductionincludePathPatterns | Create a new release pipeline |
| linear_updateReleasePipelineid*nameteamIdstypeslugIdisProductionincludePathPatterns | Update an existing release pipeline. Provide id plus at least one other field to change. |
| linear_archiveReleasePipelinepipelineId* | Archive a release pipeline |
| linear_unarchiveReleasePipelinepipelineId* | Unarchive a release pipeline |
| linear_deleteReleasePipelinepipelineId* | Delete a release pipeline |
| linear_getReleaseslimitincludeArchivedorderBypipelineIdstageId | Get releases from Linear with optional pipeline and stage filters |
| linear_getReleaseByIdid* | Get details of a specific release |
| linear_searchReleasestermlimitincludeArchivedpipelineIdstageId | Search releases by term, version, or pipeline name |
| linear_getReleaseStageslimitincludeArchivedorderBypipelineId | Get release stages from Linear |
| linear_createReleaseStagepipelineId*name*color*position*type*frozenid | Create a new release stage in a pipeline |
| linear_updateReleaseStageid*namecolorpositionfrozen | Update an existing release stage. Provide id plus at least one other field to change. |
| linear_archiveReleaseStagestageId* | Archive a release stage |
| linear_unarchiveReleaseStagestageId* | Unarchive a release stage |
| linear_getReleaseNoteslimitincludeArchivedorderBy | Get release notes from Linear |
| linear_getReleaseNoteByIdid* | Get details of a specific release note |
| linear_createReleasepipelineId*name*versiondescriptioncommitShastageIdstartDatetargetDatecreatedAtstartedAtcompletedAt | Create a new release in a release pipeline |
| linear_updateReleaseid*nameversiondescriptioncommitShapipelineIdstageIdstartDatetargetDatestartedAtcompletedAttrashed | Update an existing release. Provide id plus at least one other field to change. |
| linear_completeReleasepipelineId*version | Mark a release as completed within a pipeline. The target pipeline must already have a completed release stage configured. |
| linear_archiveReleasereleaseId* | Archive a release |
| linear_unarchiveReleasereleaseId* | Unarchive a release |
| linear_addIssueToReleaseissueId*releaseId* | Add an issue to a release |
| linear_removeIssueFromReleaseissueId*releaseId* | Remove an issue from a release |
| linear_createReleaseNotepipelineId*contentreleaseIdsrangeFromReleaseIdrangeToReleaseId | Create a release note using either explicit release IDs or a release range within a pipeline |
| linear_updateReleaseNoteid*contentreleaseIdsrangeFromReleaseIdrangeToReleaseId | Update a release note using either explicit release IDs or a release range. Provide id plus at least one other field to change. |
| linear_deleteReleaseNoteid* | Delete a release note |
| linear_getMilestonesincludeArchivedlimitprojectIdteamIdstatusorderBy | Get project milestones from Linear, with PM-friendly filters for project, team, and milestone status |
| linear_getMilestoneByIdid* | Get details of a specific project milestone by ID |
| linear_createMilestonename*projectId*descriptiontargetDatesortOrder | Create a new project milestone in Linear |
| linear_updateMilestoneid*nameprojectIddescriptiontargetDatesortOrder | Update an existing project milestone in Linear. Provide id plus at least one other field to change. |
| linear_archiveMilestoneid* | Archive a project milestone |
| linear_getDocumentslimitincludeArchivedorderByprojectIdinitiativeIdteamIdissueIdreleaseIdcycleIdtitle | Get workspace documents from Linear |
| linear_getDocumentByIdid* | Get details of a specific Linear document |
| linear_getProjectDocumentsprojectId*limitincludeArchivedorderBytitle | Get documents for a specific Linear project |
| linear_getInitiativeDocumentsinitiativeId*limitincludeArchivedorderBytitle | Get documents for a specific Linear initiative |
| linear_getTeamDocumentsteamId*limitincludeArchivedorderBytitle | Get documents associated with a specific Linear team |
| linear_getIssueDocumentsissueId*limitincludeArchivedorderBytitle | Get documents associated with a specific Linear issue |
| linear_getReleaseDocumentsreleaseId*limitincludeArchivedorderBytitle | Get documents associated with a specific Linear release |
| linear_getCycleDocumentscycleId*limitincludeArchivedorderBytitle | Get documents associated with a specific Linear cycle |
| linear_getTeamResourcesteamId* | Get team home resource sections and pinned documents or external links |
| linear_searchDocumentsterm*teamIdincludeCommentslimitincludeArchivedorderBysnippetSize | Search Linear documents by term |
| linear_getDocumentContentHistoryid* | Get content history entries for a Linear document content record |
| linear_createDocumenttitle*contenticoncolorprojectIdinitiativeIdteamIdissueIdreleaseIdcycleIdresourceFolderIdlastAppliedTemplateIdsortOrder | Create a new Linear document |
| linear_updateDocumentid*titlecontenticoncolorhiddenAtprojectIdinitiativeIdteamIdissueIdreleaseIdcycleIdresourceFolderIdlastAppliedTemplateIdsortOrdertrashed | Update an existing Linear document. Provide id plus at least one other field to change. |
| linear_archiveDocumentid* | Archive (trash) a Linear document |
| linear_unarchiveDocumentid* | Restore a previously archived Linear document |
| linear_getRateLimitStatus | Get the shared MCP-side Linear rate-limit cooldown and retry snapshot |
| linear_getServerStatus | Get MCP Linear server runtime status, counts, and current rate-limit snapshot |
| linear_generateOAuthApplicationSetupname*developer*developerUrldescriptionimageUrldistributionredirectUris*grantTypeswebhookEnabledwebhookUrlwebhookResourceTypes | Generate an official Linear OAuth application manifest and a human-confirmed setup URL. This does not create the application; an authorized workspace admin or owner must review and submit it in Linear. |
| linear_generateOAuthAuthorizationUrlclientId*redirectUri*scopes*actorstatepromptConsentcodeChallenge | Generate a Linear OAuth authorization URL. Scopes are requested during authorization; this tool does not create, grant, approve, persist, or modify scopes. Actor/scope rules: with actor: "app" the admin scope is rejected, and the agent-only scopes (app:assignable, app:mentionable, customer:read, customer:write, initiative:read, initiative:write) require actor: "app". |
| linear_createOAuthClientCredentialsTokenclientId*clientSecret*scopes*confirmSecretExposure*confirmScopeChangeRisk* | Issue a scoped Linear app-actor access token through the client_credentials grant for server-to-server pipelines. The token is returned once, has no refresh token, and is normally valid for 30 days. If the requested scope set differs from existing app-actor tokens, Linear revokes those existing tokens. |
| linear_getManagedOAuthApplications | List alpha child OAuth applications owned by the calling OAuth application. This is not a workspace-wide OAuth application admin listing and does not work as generic scope CRUD. |
| linear_getManagedOAuthApplicationByIdid* | Get an alpha child OAuth application owned by the calling OAuth application. It cannot retrieve an arbitrary workspace OAuth application. |
| linear_createManagedOAuthApplicationname*developer*developerUrldescriptionimageUrlredirectUris*grantTypesidempotencyKeywebhookUrlwebhookResourceTypesconfirmSecretExposure* | Create an alpha child OAuth application owned by the calling OAuth application. This is not the human setup flow and returns one-time client and optional webhook secrets in the MCP result. It cannot set distribution or pre-grant OAuth scopes. |
| linear_updateManagedOAuthApplicationid*namedeveloperdeveloperUrldescriptionimageUrlredirectUrisgrantTypeswebhookEnabledwebhookUrlwebhookResourceTypes | Update metadata, grant capabilities, or webhook configuration for an alpha child app owned by the calling OAuth application. This does not grant or approve token scopes. |
| linear_archiveManagedOAuthApplicationid* | Archive an alpha child OAuth application owned by the calling OAuth application. This does not revoke an unrelated authorized application. |
| linear_rotateManagedOAuthApplicationSecretid*confirmSecretExposure* | Rotate the client secret of an alpha child app owned by the calling OAuth application. The new one-time secret is exposed in the MCP result and existing client-credentials tokens may be invalidated. |
| linear_rotateManagedOAuthApplicationWebhookSecretid*confirmSecretExposure* | Rotate the webhook signing secret of an alpha child app owned by the calling OAuth application. The new one-time secret is exposed in the MCP result. |
| linear_getWebhookByIdid* | Get one ordinary workspace webhook by ID. |
| linear_getWebhooksteamIdlimitincludeArchivedorderBy | Get a list of webhooks |
| linear_createWebhookurl*resourceTypes*teamIdenabledlabelsecretallPublicTeams | Create a webhook for integration events |
| linear_updateWebhookid*urllabelenabledresourceTypessecret | Update an ordinary workspace webhook. |
| linear_rotateWebhookSecretid*confirmSecretExposure* | Rotate an ordinary workspace webhook signing secret. |
| linear_deleteWebhookid* | Delete a webhook |
| linear_getAttachmentsissueId*limitincludeArchivedorderBy | Get attachments for an issue |
| linear_addAttachmentissueId*title*url*subtitleiconUrlmetadatacommentBodygroupBySource | Add an attachment to an issue |
| linear_getNotificationslimitincludeArchivedorderBy | Get notifications for the current user |
| linear_markNotificationAsReadid* | Mark a notification as read |
| linear_getSubscriptionslimitincludeArchivedorderBy | Get subscriptions for the current user |
| linear_markAllNotificationsAsReadlimit | Mark all notifications as read |
| linear_getUnreadNotificationCountlimit | Get count of unread notifications |
| linear_getAuthenticationSessions | Get active authentication sessions |
| linear_logoutSessionsessionId* | Revoke a specific session |
| linear_logoutOtherSessions | Revoke all other sessions |
| linear_logoutAllSessions | Revoke all sessions |
| linear_getOrganizationAuditEventslimitincludeArchivedorderBy | Get audit events for the organization |
| linear_getUserAuditEventsuserId*limitincludeArchivedorderBy | Get audit events for a specific user |
| linear_getIntegrationslimitincludeArchivedorderBy | Get a list of active integrations |
| linear_getSavedViewslimitincludeArchivedorderBy | Get Linear saved views (API: CustomView) |
| linear_createSavedViewname*descriptionsharediconcolorteamIdprojectIdownerIdfiltersfilterDataprojectFilterData | Create a Linear saved view (API: createCustomView) |
| linear_updateSavedViewid*namedescriptionsharediconcolorteamIdprojectIdownerIdfiltersfilterDataprojectFilterData | Update a Linear saved view (API: updateCustomView). Provide id plus at least one other field to change. |
| linear_deleteSavedViewid* | Delete a Linear saved view (API: deleteCustomView) |
| linear_getFavoriteViewslimitincludeArchivedorderBy | Get favorite Linear views, including saved views and predefined views |
| linear_addToFavoritesentityId* | Add an entity to the current user's Linear favorites |
| linear_removeFromFavoritesfavoriteIdentityId | Remove an entity or favorite entry from the current user's Linear favorites. Provide either favoriteId or entityId. |
| linear_getCyclesteamIdlimit | Get a list of all cycles |
| linear_getCycleByIdid* | Get details of a specific cycle |
| linear_createCycleteamId*startsAt*endsAt*namedescriptioncompletedAt | Create a new cycle |
| linear_updateCycleid*startsAtendsAtnamedescriptioncompletedAt | Update an existing cycle. Provide id plus at least one other field to change. |
| linear_completeCycleid* | Mark a cycle as complete |
| linear_getCycleStatsid* | Get statistics for a cycle |
| linear_getActiveCycleteamId* | Get the currently active cycle for a team |
| linear_getCycleIssuescycleId*limitstatesassigneeIdlabelIdsincludeCompletedorderBy | Get issues in a cycle, with PM-friendly filters like state, assignee, labels, and completion status |
| linear_addIssueToCycleissueId*cycleId* | Add an issue to a cycle |
| linear_removeIssueFromCycleissueId*cycleId* | Remove an issue from a cycle |
| linear_getInitiativesincludeArchivedlimit | Get a list of all initiatives from Linear |
| linear_getInitiativeByIdinitiativeId*includeProjects | Get details of a specific initiative by ID |
| linear_createInitiativename*descriptioncontentownerIdtargetDatestatusiconcolor | Create a new initiative |
| linear_updateInitiativeinitiativeId*namedescriptioncontentownerIdtargetDatestatusiconcolor | Update an existing initiative |
| linear_archiveInitiativeinitiativeId* | Archive an initiative |
| linear_unarchiveInitiativeinitiativeId* | Unarchive an initiative |
| linear_deleteInitiativeinitiativeId* | Delete an initiative (move to trash) |
| linear_getInitiativeProjectsinitiativeId*includeArchived | Get all projects associated with an initiative |
| linear_getInitiativeUpdateByIdid* | Get a specific initiative update by ID |
| linear_getInitiativeUpdatesinitiativeId*limit | Get updates for an initiative |
| linear_createInitiativeUpdateinitiativeId*body*healthisDiffHidden | Create a new initiative update |
| linear_updateInitiativeUpdateid*bodyhealthisDiffHidden | Update an existing initiative update |
| linear_archiveInitiativeUpdateid* | Archive an initiative update |
| linear_unarchiveInitiativeUpdateid* | Restore an archived initiative update |
| linear_addProjectToInitiativeinitiativeId*projectId* | Add a project to an initiative |
| linear_removeProjectFromInitiativeinitiativeId*projectId* | Remove a project from an initiative |
| linear_getCustomerslimitincludeArchivedorderBynamedomainstatusIdtierIdownerId | Get customers from Linear |
| linear_getCustomerByIdid* | Get a customer by ID |
| linear_createCustomername*domainsexternalIdslogoUrlmainSourceIdownerIdrevenuesizeslackChannelIdstatusIdtierId | Create a customer |
| linear_updateCustomerid*namedomainsexternalIdslogoUrlmainSourceIdownerIdrevenuesizeslackChannelIdstatusIdtierId | Update a customer |
| linear_deleteCustomerid* | Delete a customer |
| linear_getCustomerNeedslimitincludeArchivedorderBycustomerIdissueIdprojectIdpriority | Get customer needs from Linear |
| linear_getCustomerNeedByIdid* | Get a customer need by ID |
| linear_createCustomerNeedattachmentIdattachmentUrlbodycommentIdcreatedAtcustomerExternalIdcustomerIdissueIdpriorityprojectId | Create a customer need linked to an issue or project |
| linear_createCustomerNeedFromAttachmentattachmentId*customerIdcustomerExternalIdpriority | Create or unarchive a customer need from an existing attachment |
| linear_updateCustomerNeedid*applyPriorityToRelatedNeedsattachmentUrlbodycustomerExternalIdcustomerIdissueIdpriorityprojectId | Update a customer need |
| linear_archiveCustomerNeedid* | Archive a customer need |
| linear_unarchiveCustomerNeedid* | Restore an archived customer need |
| linear_deleteCustomerNeedid* | Delete a customer need |
| linear_getCustomerStatuseslimitincludeArchivedorderBy | Get customer statuses from Linear |
| linear_getCustomerTierslimitincludeArchivedorderBy | Get customer tiers from Linear |
| linear_getIssueslimit | Get a list of recent issues from Linear |
| linear_getIssueByIdid* | Get a specific issue by ID or identifier (e.g., ABC-123) |
| linear_getCustomFields | Get the custom field definitions available in the authenticated Linear workspace |
| linear_getIssueCustomFieldsissueId* | Get the custom field values that are currently set on a specific issue |
| linear_searchIssuesqueryteamIdassigneeIdprojectIdstateslimit | Search for issues with various filters |
| linear_createIssuetitle*descriptionteamId*assigneeIdpriorityprojectIdprojectMilestoneIdcycleIdestimatedueDatelabelIdsparentIdsubscriberIdsstateIdtemplateIdsortOrder | Create a new issue in Linear |
| linear_updateIssueid*titledescriptionstateIdpriorityprojectIdprojectMilestoneIdassigneeIdcycleIdestimatedueDatelabelIdsaddedLabelIdsremovedLabelIdsparentIdsubscriberIdsteamIdsortOrder | Update an existing issue in Linear |
| linear_updateIssueCustomFieldissueId*customFieldId*value* | Set or clear a custom field value on an issue. Pass null as value to clear it. |
| linear_createCommentissueIdprojectIdinitiativeIdprojectUpdateIdinitiativeUpdateIddocumentContentIdpostIdbody*parentIdquotedTextsubscriberIds | Add a comment to an issue, project, initiative, update, document content, or as a threaded reply |
| linear_updateCommentid*bodyquotedTextresolvingCommentIdresolvingUserIdsubscriberIdsdoNotSubscribeToIssue | Update an existing comment |
| linear_deleteCommentid* | Delete a comment |
| linear_addIssueLabelissueId*labelId* | Add a label to an issue in Linear |
| linear_removeIssueLabelissueId*labelId* | Remove a label from an issue in Linear |
| linear_getIssueTemplateslimitincludeArchivedorderBy | Get a list of issue templates |
| linear_getIssueTemplateByIdid* | Get details of a specific issue template |
| linear_createIssueTemplatename*descriptionteamIdtemplateData*sortOrder | Create a new issue template |
| linear_updateIssueTemplateid*namedescriptionteamIdtemplateDatasortOrder | Update an existing issue template. Provide id plus at least one other field to change. |
| linear_createIssueFromTemplateteamId*templateId*titledescriptionpriorityprojectIdprojectMilestoneIdcycleId | Create a new issue from a template |
| linear_getTeamTemplatesteamId*limitincludeArchivedorderBy | Get templates for a specific team |
| linear_archiveTemplateid* | Archive an issue template |
| linear_assignIssueissueId*assigneeId* | Assign an issue to a user |
| linear_subscribeToIssueissueId* | Subscribe to issue updates |
| linear_convertIssueToSubtaskissueId*parentIssueId* | Convert an issue to a subtask |
| linear_createIssueRelationissueId*relatedIssueId*type* | Create relations between issues (blocks, is blocked by, etc.) |
| linear_deleteIssueRelationid* | Delete an issue relation by ID |
| linear_archiveIssueissueId* | Archive an issue |
| linear_setIssuePriorityissueId*priority* | Set the priority of an issue |
| linear_transferIssueissueId*teamId* | Transfer an issue to another team |
| linear_duplicateIssueissueId* | Duplicate an issue |
| linear_getIssueHistoryissueId*limit | Get the history of changes made to an issue |
| linear_getCommentsissueIdprojectIdinitiativeIdprojectUpdateIdinitiativeUpdateIddocumentContentIdpostIdlimitcursororderBy | Get comments for an issue, project, initiative, update, or document content |
Parameters marked with * are required.
Setup
Copy the block for the app you use. Each one is the configuration this server was verified with.
Open the file ~/Library/Application Support/Claude/claude_desktop_config.json (in Claude Desktop: Settings, then Developer, then Edit Config) and add:
{
"mcpServers": {
"linear": {
"command": "npx",
"args": [
"-y",
"@tacticlaunch/mcp-linear"
],
"env": {
"LINEAR_API_TOKEN": "your_linear_api_key"
}
}
}
}Paste your own Linear API key in place of your_linear_api_key, then quit and reopen Claude Desktop. Claude Desktop can also reach Linear's hosted server without any of this: Linear documents adding its Linear connector from Claude settings, then Connectors, which logs you in instead of asking for a key. [8][6]
One command in your terminal:
claude mcp add linear -e LINEAR_API_TOKEN=your_linear_api_key -- npx -y @tacticlaunch/mcp-linear
Everything after the double dash is the exact command Claude Code will run, and -e sets the key in that command's environment. For Linear's hosted server instead, Linear documents claude mcp add --transport http linear-server https://mcp.linear.app/mcp, which opens an OAuth login rather than taking a key. [9][6]
Add to ~/.cursor/mcp.json for every project, or to .cursor/mcp.json inside one project:
{
"mcpServers": {
"linear": {
"command": "npx",
"args": [
"-y",
"@tacticlaunch/mcp-linear"
],
"env": {
"LINEAR_API_TOKEN": "your_linear_api_key"
}
}
}
}Cursor picks the file up on restart. Linear also lists a one-click install of its own hosted server from Cursor's MCP tools page, which uses an OAuth login instead of a key. [10][6]
No JSON file and no terminal. In Routines: Settings, then Assistant, then Connections, then Add MCP Server. Switch the form to Command (stdio) and enter:
Name Linear Command npx Arguments -y @tacticlaunch/mcp-linear Environment LINEAR_API_TOKEN=your_linear_api_key
Put the key in the Environment Variables field, not in Arguments. Click Test Connection first: it answers with the tool count, 198 for this server. Worth knowing before you trust that number: in our run the server listed all 198 tools even with a deliberately fake token, because it only checks the key when a tool actually runs. A green test means the server started, not that your key is valid. [11]
No terminal needed
If you have never opened Terminal and never want to, this is your path. Routines is a Mac app that runs MCP servers for you: fill in a few fields once, and this server's tools are available to your AI in chat and in scheduled routines.
01
Download the app from getroutines.ai/download, drag it to Applications, and sign in.
02
Click your account at the bottom of the sidebar and choose Settings. Open the Assistant section, then the Connections tab, scroll to MCP Servers, and click Add MCP Server.
03
Switch the form to Command (stdio): this server is a command your Mac runs, not a web address. Linear also hosts its own server at a web address, but that one signs you in through your browser instead of taking a key.
04
This server will not start without one, as our own run proved. In Linear, open Settings, then Account, then Security & Access, and generate a new API key. Copy it straight away and keep it somewhere safe: the package we ran warns you will not be able to see it again. It is issued under your own Linear account, so treat it like a password.
05
Name: Linear. Command: npx. Arguments: -y @tacticlaunch/mcp-linear. In Environment Variables add LINEAR_API_TOKEN and paste your key as its value. Click Test Connection: Routines starts the server and reports how many tools it found, 198 for this one. Then click Add Server.
06
The tools work in chat right away. Ask for your open issues first: that is the quickest way to confirm the key itself works, since a bad key still passes the connection test but fails on the first real question. To let a scheduled routine use them, open the routine, find the Tools & connections card, and tick the server under Apps.
Routine ideas
Once the server is connected, a scheduled routine can use its tools while you are away. Copy a prompt, paste it into Routines, and pick a time.
Every Monday at 9:00, list every Linear issue assigned to me that is still open, group them by project, and write me a short plan for the week naming the three I should finish first.
Every Friday at 16:00, find the Linear issues on my team that have not moved in 14 days, and write a short list with the assignee, the current state, and the last update on each so I can chase them.
On the first of every month at 10:00, read the Linear issues my team completed since the last run and draft release notes grouped into fixes, improvements, and new features, in plain language a customer would understand.
Troubleshooting
Real errors captured during the verification run, printed exactly as the server returned them.
What you see
Error: Authentication required, not authenticated - You need to authenticate to access this operation.
The fix
The server started, so your config is right, but Linear rejected the key. This is the exact error our own run produced on purpose with a placeholder token. Check that LINEAR_API_TOKEN holds a real key generated in Linear under Settings, then Account, then Security & Access, that you copied all of it, and that the key has not been revoked. Note that the tool list works regardless: a wrong key only shows up on the first real call.
What you see
API token not found in command line args or environment variables Error starting MCP Linear Error: Linear credentials not found. Provide an API token via --token, LINEAR_API_TOKEN, or LINEAR_API_KEY, or sign in with `mcp-linear auth login`.
The fix
No credential reached the server, so it refused to boot. In a JSON config the key belongs in the "env" object, not in "args"; in Routines it belongs in Environment Variables. The message names every variable the server accepts, so LINEAR_API_TOKEN or LINEAR_API_KEY will both do.
What you see
www-authenticate: Bearer realm="OAuth", resource_metadata="https://mcp.linear.app/.well-known/oauth-protected-resource/mcp", error="invalid_token", error_description="Missing or invalid access token"
{"error":"invalid_token","error_description":"Missing or invalid access token"}The fix
Working as designed, and we triggered it on purpose: https://mcp.linear.app/mcp refuses anonymous callers. It is not a server you configure with a pasted key by default, it expects your client to walk you through an OAuth login in the browser. Use a client that supports that flow, or use the local stdio server on this page with an API key instead.
What you see
Error: Invalid arguments for getWorkflowStates
The fix
A required parameter is missing. We produced this one by calling linear_getWorkflowStates with no teamId. The tool table above marks which parameters are required, so ask the assistant to fetch the parent object first, teams before workflow states for instance, and pass the id it returns.
What you see
Error: Unknown tool: linear_deleteEverything
The fix
The server rejects any name outside the 198 it published, which is the reply we got when we made one up. If your assistant keeps reaching for a tool that is not there, point it at the tool table above; with a list this long, models sometimes guess a plausible name instead of reading the list.
The fix
The npx command belongs to Node.js. If Node is not installed on your Mac, every client on this page fails at the spawn step before the server can say anything. Install Node from nodejs.org, restart your MCP client, and try again.
FAQ
It is a bridge that lets an AI assistant work in Linear: find issues, create and update them, read projects and cycles, and post comments, all in the words you would use with a colleague. There is more than one. Linear runs an official hosted server that your AI app signs into, and the community publishes packages you run on your own Mac with an API key. This page enumerates the community one and probes the official one. [6][5]
Yes. Linear documents and hosts one at https://mcp.linear.app/mcp, using Streamable HTTP with an OAuth 2.1 login, and a read-only variant at https://mcp.linear.app/mcp/readonly. We confirmed both addresses are live: each answered our unauthenticated request with a 401 pointing at its OAuth metadata, and that metadata lists read and write as the available scopes. Linear also documents setup pages for Claude, Cursor, VS Code, Windsurf, and Zed. [6][7]
We verified that the server starts, speaks MCP protocol 2025-06-18, reports itself as linear 1.4.1, and publishes 198 tools, and we captured the exact errors it returns when the credential is missing, wrong, or the arguments are bad. We did not verify any authenticated result: reading or writing a real issue needs a Linear API key from a real workspace, and we ran everything with a placeholder. So treat the tool list as proven and the outcomes of those tools as untested here.
The package we ran publishes 198, which is a lot for an MCP server: issues, comments, projects and project updates, teams and memberships, cycles, initiatives, roadmaps, milestones, releases and release notes, documents, labels, webhooks, and a set of OAuth application tools. The table above is the live tools/list output, word for word. It only describes this package. We could not enumerate Linear's own hosted server without logging in, so for that one we can only repeat Linear's description: tools for finding, creating, and updating objects like issues, projects, and comments, with more on the way. [6]
In Linear, open Settings, then Account, then Security & Access, and generate a new API key. Copy it straight away and store it somewhere safe: the package we ran warns you will not be able to see it again. It is a personal key issued under your own Linear account, so treat it like a password. If a routine only needs to read, Linear offers narrower options than a full personal key: a read-only hosted endpoint, or an OAuth token that requests only the read scope. [6][5]
No. In Routines you fill in a few fields in Settings, paste the key into Environment Variables, and click Test Connection; the walkthrough above shows every click. Claude Desktop needs a small JSON file edited once, or Linear's connector added from its settings. Only Claude Code is terminal-first by nature. [11][6]
For the local stdio package, any MCP client that can launch a command: Claude Desktop, Claude Code, Cursor, and Routines all can, and the exact config for each is above. For Linear's hosted server, you need a client that can do the OAuth login, and Linear documents Claude, Claude Code, Cursor, Codex, VS Code, Windsurf, and Zed by name. [8][9][10][11][6]
Sources
Anything on this page we did not observe in the run is linked here, with the date we read it. The run itself is the receipt for the rest.
[1]
Latest version 1.4.1, published 2026-07-28; first published 2025-03-23.
[2]
4,457 downloads for the week ending 2026-08-01. We checked the 20 Linear MCP packages the npm search returns; the runner-up had 1,236.
[3]
144 stars, 34 forks and a push dated 2026-07-28 at access time, per the GitHub API.
[4]
MIT License, confirmed by the GitHub license API.
[5]
Documents LINEAR_API_TOKEN in the env object and the --token flag.
[6]
Linear's own page: Streamable HTTP at mcp.linear.app/mcp, OAuth 2.1 with dynamic client registration, a /mcp/readonly variant, and per-client setup including the API-key path under Settings, Account, Security & Access.
[7]
Served 200 to an anonymous request: scopes_supported lists read and write, bearer_methods_supported lists header.
[8]
The claude_desktop_config.json shape and where the file lives.
[9]
The claude mcp add syntax, including -e for environment variables.
[10]
[11]
How Routines runs one-click OAuth connectors and any MCP server.
This page describes Linear as it behaved in one dated run on one Mac. Versions move: if something here no longer matches what you see, the capture date at the top says how old the reading is.
Behind this directory
Routines, the app behind this directory, runs MCP servers like this one without a terminal: see how connectors work. Your notes stay markdown files on your Mac, there is no cloud bill, and it works offline. Download Routines