Atlas / MCP servers / iceener / Linear Streamable

Linear StreamableBLOCK

mcp/iceener/linear-streamable

MCP Server for interacting with Linear API. Written in TypeScript, Node and Hono.dev

Verdict
BLOCK
Grade
F
Trust score
54 /100
Exposed tools
1 1r · 0w · 0d
Transport
streamable-http
License
MIT
Stars
71
01

Overview

From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.

This server is a remote Model Context Protocol (MCP) server for Linear. A model can use it to find, read, create and update issues, comments and projects, and to read teams, users and cycles. The server runs on Cloudflare Workers and on Bun. It uses the MCP server template 2.1 and the official MCP TypeScript SDK 2.3.0.

The server URL is the deployed Worker's MCP_PUBLIC_URL, for example https://linear-mcp..workers.dev/mcp.

The server uses protocol version 2026-07-28. It also accepts clients that use the 2025 protocol versions.

[!WARNING] You connect this server to your MCP client at your own risk. A model can make mistakes. Examine what the tools do, and examine the changes in Linear. The write tools change issues, comments and projects in your workspace.

Tools

Read from source at commit 5d6cb9b8a6afOBSERVED · 2026-10-07
02

Connect

Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.

claude-code
claude mcp add linear-mcp --env LINEAR_TEST_TOKEN=${LINEAR_TEST_TOKEN} -- npx -y linear-mcp
claude-desktop
{
  "mcpServers": {
    "linear-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "linear-mcp"
      ],
      "env": {
        "LINEAR_TEST_TOKEN": "${LINEAR_TEST_TOKEN}"
      }
    }
  }
}
03

Exposed tools (1)

1 read · 0 write · 0 destructive.

ToolRiskDescription
EngineeringreadCore engineering team
04

Trust audit

BLOCKgrade F · trust 54/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.

LayerWhat it checksResult
L0Provenance & inventoryPASS
L1Static analysis of the codeFAIL
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfacePASS
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
UNDECLARED (4 observation(s))
Network
declared (10 observation(s))
Shell
declared (3 observation(s))
Dependencies
pinned
Secrets in source
found

Findings (21)

HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
worker-configuration.d.ts:3146
exec(input?: (string | URLPatternInit), baseURL?: string): URLPatternResult | null;
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
worker-configuration.d.ts:3448
exec(cmd: string[], options?: ContainerExecOptions): Promise<ExecProcess>;
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
worker-configuration.d.ts:13065
exec(query: string): Promise<D1ExecResult>;
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
MEDIUMInformation disclosure · disclose.log_secret · CWE-209, CWE-532
src/oauth/verifier.ts:142
logger.error(`${options.provider.name} token refresh failed; using the current token`, {
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
.env.example:15
# Defaults to http://127.0.0.1:$PORT/mcp outside production; required in production.
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
.env.example:16
# MCP_PUBLIC_URL=http://127.0.0.1:3000/mcp
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
.env.example:32
OAUTH_ISSUER_URL=http://127.0.0.1:3000
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
.env.example:33
OAUTH_AUTHORIZATION_URL=http://127.0.0.1:3000/authorize
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
.env.example:34
OAUTH_TOKEN_URL=http://127.0.0.1:3000/token
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
tests/auth.test.ts:350
const TOKEN = 'a-long-random-shared-secret';
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
src/tools/shared/linear.ts:3
import { providerToken } from '../../oauth/verifier';
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
src/tools/shared/linear.ts:4
import type { Logger } from '../../platform/logger';
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
src/tools/shared/linear.ts:5
import { type ToolErrorResult, toolError } from '../../platform/primitives';
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
src/tools/shared/linear.ts:6
import type { Deps } from '../../server';
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
tests/live/linear-api.test.ts:21
import { createIssues } from '../../src/tools/create-issues';
LOWObfuscation / stealth · obf.decode_call · CWE-506, CWE-94
src/oauth/encoding.ts:17
const binary = atob(base64.padEnd(Math.ceil(base64.length / 4) * 4, '='));
LOWObfuscation / stealth · obf.decode_call · CWE-506, CWE-94
worker-configuration.d.ts:312
atob(data: string): string;
LOWObfuscation / stealth · obf.decode_call · CWE-506, CWE-94
worker-configuration.d.ts:400
declare function atob(data: string): string;
LOWPrompt injection · prompt.credential_read · CWE-94, CWE-1427
docs/deploy.md:78
The Worker writes JSON logs to Workers Logs. A tool error that the model sees as "internal error (reference ...)" has its details in the logs under that reference. Linear API errors are shown to the m
Why it matters. asks the agent to read credentials
LOWPrompt injection · prompt.credential_read · CWE-94, CWE-1427
docs/oauth.md:103
**Issued tokens (Workers KV `TOKENS`).** Each record is written twice, as `rs:access:<access token>` and `rs:refresh:<refresh token>`:
Why it matters. asks the agent to read credentials
INFOInventory / provenance · inv.oversize · CWE-1104
docs/comparison-hd.gif
docs/comparison-hd.gif
Why it matters. 16699200 bytes not read

Gates applied: no_behavioural_pass.

Audited 2026-10-07 · audit v0.4.1 · source sha 5d6cb9b8a6affull audit observations/trust-audit/mcp-server/iceener__linear-streamable.json · Report an issue / request a re-scan
05

Audit history

Every audit this server has had. A grade with a past is a grade somebody is still checking.

DateSourceVerdictGradeScoreChange
2026-10-075d6cb9b8a6afBLOCKF54first audit
06

Questions

What is the Linear Streamable MCP server?

MCP Server for interacting with Linear API. Written in TypeScript, Node and Hono.dev

What tools does Linear Streamable expose?

1 in total: 1 read-only, 0 that write, and 0 that can delete or overwrite. Every one is listed on this page with its risk.

Is Linear Streamable safe to connect to an agent?

No — not without reading the findings first. The audit graded it F (54/100) and found 3 critical or high issues in the source. Each one is listed on this page with the file and line it is on.

What credentials does Linear Streamable need?

It reads LINEAR_TEST_TOKEN from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.

How does Linear Streamable run?

It speaks streamable-http, so it runs as a service you connect to over the network. It is published on npm as linear-mcp.

How current is this page?

The grade is for one exact copy of the source (5d6cb9b8a6af), read on 2026-10-07. The repository is watched and re-audited when it changes.

Advertisement