linear-lite-mcp

radish2951/linear-lite-mcp

3.2

If you are the rightful owner of linear-lite-mcp and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.

A lightweight Linear MCP server on Cloudflare Workers designed to minimize payload size and avoid UUID floods.

Tools
4
Resources
0
Prompts
0

Linear Lite MCP Server

A lightweight Linear MCP server on Cloudflare Workers. This implementation uses GraphQL field selection to minimize payload size and avoid UUID floods.

Design Philosophy

  • Minimal Payload: Only fetch essential fields in list views
  • Two-Stage Fetch: Lean lists + detailed gets on demand
  • Flat Structure: No nested objects (e.g., assigneeName instead of assignee.name)
  • Type-Safe: Full TypeScript with Cloudflare Workers types

Available Tools

Note: Tool inputs accept human-readable names instead of IDs. The server resolves them to Linear IDs at runtime, so duplicate team/user/label names may lead to ambiguous matches—keep names unique for reliable results.

issues_list

List issues with minimal payload. Returns only essential fields:

  • identifier, title, state, priority
  • projectName (flattened)
  • dueDate

Default behavior: Excludes both completed/canceled and backlog issues.

Parameters:

  • query (optional): Freetext search across title and description
  • teamName (optional): Filter by team name (resolved to ID server-side)
  • assigneeName (optional): Filter by assignee name (resolved to ID server-side)
  • state (optional): Filter by state name
  • priority (optional): Filter by priority (0: No Priority, 1: Urgent, 2: High, 3: Medium, 4: Low)
  • limit (optional): Number of results (1-100, default: 25)
  • includeCompleted (optional): Include completed/canceled issues (default: false)
  • includeBacklog (optional): Include backlog issues (default: false)
  • updatedAt (optional): Filter by update time using ISO 8601 duration format (e.g., "-P1D" for last 24 hours, "-P7D" for last week)

issue_get

Get full issue details.

Parameters:

  • identifier (required): Issue identifier (e.g., "JHS-1")

Returns:

  • Full issue details: identifier, title, state, priority, projectName, dueDate, description, labels, assigneeName, creatorName, createdAt, updatedAt

workspace_overview

Fetch workspace metadata in a single call. Returns:

  • Teams with keys, states, labels, and active projects
  • Workspace-level labels and initiatives
  • Active users (without IDs to keep payload small)
  • Active issues: Up to 50 most recently updated issues (excludes completed, canceled, and backlog)

Parameters: None

issue_create

Create a new issue by human-friendly names. Resolves names to IDs internally before calling Linear.

Parameters:

  • teamName (required): Team to create the issue in
  • title (required): Issue title
  • description (optional): Issue description
  • priority (optional): Issue priority (0: No Priority, 1: Urgent, 2: High, 3: Medium, 4: Low)
  • assigneeName (optional): Assign by user display name
  • labelNames (optional): Array of label names (team or workspace labels)
  • projectName (optional): Associate with a project
  • stateName (optional): Set initial workflow state

Returns:

  • success: Boolean indicating if creation succeeded
  • issue.identifier: Created issue identifier

issue_update

Update an existing issue by human-friendly names. Resolves names to IDs internally before calling Linear.

Parameters:

  • identifier (required): Issue identifier (e.g., "JHS-1")
  • title (optional): New title
  • description (optional): New description
  • priority (optional): New priority (0: No Priority, 1: Urgent, 2: High, 3: Medium, 4: Low)
  • assigneeName (optional): Reassign by user display name
  • labelNames (optional): Replace labels with new array of label names
  • projectName (optional): Move to a different project
  • stateName (optional): Change workflow state

Returns:

  • success: Boolean indicating if update succeeded

documents_list

List documents with minimal payload. Returns only essential fields:

  • title, slugId

Default behavior: Excludes archived documents.

Parameters:

  • query (optional): Freetext search by document title (note: content search not supported by Linear API)
  • projectName (optional): Filter by project name (resolved to ID server-side)
  • initiativeName (optional): Filter by initiative name (resolved to ID server-side)
  • limit (optional): Number of results (1-100, default: 25)
  • includeArchived (optional): Include archived documents (default: false)

document_get

Get full document details including content.

Parameters:

  • slugId (required): Document slug ID (e.g., "roadmap-2024")

Returns:

  • Full document details: title, slugId, url, icon, color, content, createdAt, updatedAt, archivedAt, creatorName, projectName, initiativeName

document_create

Create a new document by human-friendly names. Resolves names to IDs internally before calling Linear.

Parameters:

  • title (required): Document title
  • projectName (required): Project to create the document in
  • content (optional): Document content in markdown

Returns:

  • success: Boolean indicating if creation succeeded
  • document.title: Created document title
  • document.slugId: Created document slug ID
  • document.url: Created document URL

document_update

Update an existing document by human-friendly names. Resolves names to IDs internally before calling Linear.

Parameters:

  • slugId (required): Document slug ID (e.g., "roadmap-2024")
  • title (optional): New title
  • content (optional): New content in markdown
  • projectName (optional): Move to a different project
  • initiativeName (optional): Associate with an initiative

Returns:

  • success: Boolean indicating if update succeeded

Setup

1. Install dependencies

pnpm install

2. Create a Linear OAuth Application

  1. Go to https://linear.app/settings/api/applications
  2. Click "Create new OAuth Application"
  3. Fill in the details:
    • Name: Linear Lite MCP Server (or any name you prefer)
    • Callback URLs: Add your callback URL(s):
      • For local development: http://localhost:8787/callback
      • For production: https://your-worker-name.workers.dev/callback
  4. Save the application
  5. Copy the Client ID and Client Secret - you'll need these in the next step

3. Configure Secrets and Environment Variables

Required Secrets
# For local development (.dev.vars)
cat > .dev.vars << EOF
LINEAR_OAUTH_CLIENT_ID=your_linear_oauth_client_id
LINEAR_OAUTH_CLIENT_SECRET=your_linear_oauth_client_secret
COOKIE_ENCRYPTION_KEY=$(openssl rand -base64 32)
MCP_API_KEY_SECRET=$(openssl rand -base64 32)
PUBLIC_BASE_URL=http://localhost:8787
EOF

# For production deployment
wrangler secret put LINEAR_OAUTH_CLIENT_ID
wrangler secret put LINEAR_OAUTH_CLIENT_SECRET
wrangler secret put COOKIE_ENCRYPTION_KEY
wrangler secret put MCP_API_KEY_SECRET
# Also set PUBLIC_BASE_URL as an environment variable (not a secret)
# via the Cloudflare dashboard or wrangler.jsonc

Secret Descriptions:

  • LINEAR_OAUTH_CLIENT_ID / LINEAR_OAUTH_CLIENT_SECRET: OAuth credentials from Linear
  • COOKIE_ENCRYPTION_KEY: Used to encrypt session cookies and Linear tokens in KV storage (generate with openssl rand -base64 32)
  • MCP_API_KEY_SECRET: Required for /mcp-no-oauth endpoint security (generate with openssl rand -base64 32)

Important: Each user will authenticate with their own Linear account via OAuth. The server does not use a shared API key.

Get your Linear OAuth credentials at:

4. Run locally

pnpm run dev

Server will be available at: http://localhost:8787/mcp

Note: As of MCP protocol version 2024-11-05, the standalone SSE transport is deprecated in favour of Streamable HTTP.1 This server therefore exposes only the Streamable HTTP endpoint at /mcp.

5. Deploy to Cloudflare

pnpm run deploy

After deployment, don't forget to update your Linear OAuth application's callback URL to include your production URL: https://your-worker-name.workers.dev/callback

Usage Examples

Freetext search

{
  "query": "ヒアリング"
}

Search issues by state

{
  "state": "In Progress",
  "limit": 10
}

Search high priority issues

{
  "priority": 1,
  "state": "Todo"
}

Combined search

{
  "query": "API",
  "state": "In Progress"
}

Search recently updated issues

{
  "updatedAt": "-P1D",
  "teamName": "Product"
}

Create an issue

{
  "teamName": "Product",
  "title": "API モニタリングを追加",
  "assigneeName": "Daiki",
  "labelNames": ["Backend"],
  "priority": 2
}

Update an issue

{
  "identifier": "JHS-1",
  "stateName": "Done",
  "priority": 1
}

Get issue details

{
  "identifier": "JHS-1"
}

Fetch workspace overview

{}

List documents

{
  "projectName": "Engineering",
  "limit": 10
}

Search documents by title

{
  "query": "roadmap",
  "projectName": "Product"
}

Get document details

{
  "slugId": "roadmap-2024"
}

Create a document

{
  "title": "API Design Guidelines",
  "projectName": "Engineering",
  "content": "# API Design Guidelines\n\n## REST API Standards\n..."
}

Update a document

{
  "slugId": "api-design-guidelines",
  "content": "# Updated API Design Guidelines\n\n## REST API Standards\n...",
  "initiativeName": "Platform Improvement"
}

Authentication Flow

When you first connect to this MCP server from Claude.ai or Claude Desktop:

  1. You'll be redirected to the Linear OAuth authorization page
  2. Log in with your Linear account and grant permissions
  3. You'll be redirected back to the MCP server
  4. The server will store your Linear access token securely
  5. All subsequent Linear API calls will use your own Linear account

Each user authenticates with their own Linear account, so you can only access the Linear workspaces and issues you have permission to view.

Connect to Claude Web (claude.ai)

  1. Go to Claude.ai
  2. Click on your profile → Settings → Integrations
  3. Add a new MCP server:
    • URL: https://your-worker-name.workers.dev/mcp
  4. Follow the OAuth flow to authenticate with Linear

Connect to Claude Desktop

Add to your Claude Desktop config (~/.config/Claude/claude_desktop_config.json):

{
  "mcpServers": {
    "linear-lite": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "http://localhost:8787/mcp"
      ]
    }
  }
}

For production, replace with your deployed URL: https://your-worker.workers.dev/mcp

When you first use the server, you'll be prompted to authenticate via OAuth in your browser.


: Model Context Protocol documentation, “Server-Sent Events (SSE) - Deprecated”.

Why Lightweight?

Traditional Linear integrations often return bloated payloads with:

  • Full UUID chains for every nested object
  • Unnecessary fields in list views
  • Deep object nesting

This implementation:

  • ✅ Returns only 7 fields in list views (vs. 20+ in typical implementations)
  • ✅ Flattens nested objects to reduce token usage
  • ✅ Separates "list" and "detail" operations
  • ✅ Uses GraphQL field selection to avoid over-fetching

Result: ~70% smaller payloads for list operations.

Implementation Details

  • Authentication: Linear OAuth 2.0 - each user authenticates with their own Linear account
  • GraphQL Client: Minimal fetch-based implementation (no Apollo overhead)
  • Type Safety: Full TypeScript with Cloudflare Workers bindings
  • Security: OAuth tokens stored securely in Durable Objects session storage
  • Rate Limiting: Respects Linear's rate limits automatically
  • Multi-User: Supports multiple users, each with their own Linear workspace access

Future Enhancements

  • Issue updates
  • Document management (list, get, create, update)
  • Project and Initiative search
  • Webhook support for real-time updates
  • Pagination with cursor support