Skip to main content

OhMyLinearMCP - unified Linear MCP (local-fast reads + official fallback/writes) on macOS

Project description

Oh My Linear MCP

Ask your AI agent to list Linear issues. Watch 37,000 tokens vanish into a single response full of avatar URLs, custom field schemas, and nested workspace metadata nobody asked for. Congratulations -- your context window is now half gone before the real work begins.

This is what happens when every list_issues call goes through the official Linear MCP. The responses are accurate. They're also enormous.

oh-my-linear reads directly from Linear.app's local IndexedDB cache instead. No API call. No network round-trip. Just the fields you actually care about.

"Give me the issues for team Frontend"

Official MCP:  ~37,500 tokens (nested GraphQL, full user objects, attachment metadata, ...)
oh-my-linear: ~2,500 tokens (identifier, title, priority, state, assignee, dueDate)

Same question. 15x less context.

How It Works

Linear.app is an Electron app. Every time you open it, it syncs your workspace into a local IndexedDB (LevelDB on disk). oh-my-linear cracks open that database, parses the binary Chromium storage format, and serves the data as MCP tool responses.

Linear.app (Electron)
  -> syncs workspace to local IndexedDB
  -> oh-my-linear reads it directly
     -> reads:  local cache (no API call, <10ms)
     -> writes: proxied to official Linear MCP
     -> after a write: 30s remote-first window to avoid stale reads

Writes still go through the official MCP -- this isn't trying to replace it. It's a read accelerator that sits in front of it.

The Store Detection Trick

Linear uses hash-based IndexedDB store names that change between app versions. Something like fbaa32a232c2_issues today might be a1b2c3d4e5f6_issues tomorrow. Instead of hardcoding these, oh-my-linear samples the first record from each store and matches the shape -- "has teamId, stateId, title? That's the issues store." Survives Linear updates without code changes.

Setup

One server handles both reads and writes. Replace your existing Linear MCP with this.

Claude Code

# Project scope (default — only this project)
claude mcp add oh-my-linear -- uvx oh-my-linear

# User scope (all projects for this user)
claude mcp add --scope user oh-my-linear -- uvx oh-my-linear

From local checkout:

claude mcp add oh-my-linear -- uvx --from /path/to/oh-my-linear oh-my-linear

Claude Desktop / Cursor / VS Code / Windsurf

{
  "mcpServers": {
    "oh-my-linear": {
      "command": "uvx",
      "args": ["oh-my-linear"]
    }
  }
}

Codex

Use CLI (recommended):

codex mcp add oh-my-linear -- uvx oh-my-linear
codex mcp list
codex mcp get oh-my-linear

Manual config (~/.codex/config.toml):

[mcp_servers.oh-my-linear]
command = "uvx"
args = ["oh-my-linear"]

Scope Guide

Client Default scope How to change
Claude Code Project (.mcp.json) Add --scope user for user-wide
Claude Desktop Per-app config N/A
Cursor / VS Code Per-app config N/A
Codex Global (~/.codex/config.toml) N/A

Requirements

  • macOS (Linear.app cache path is macOS-specific)
  • Linear.app installed and opened at least once
  • Node.js/npm (npx) for official MCP bridge (mcp-remote)
  • Network access for writes and fallback reads

Read/Write Policy

Operation What happens
Read Local cache first. If local handler cannot serve the request, falls back to official MCP.
Write Always goes to official MCP.
Read after write No built-in remote-first coherence window; reads remain local-first unless local fallback is required.

Available Tools

Local Read Tools (cache-first, fast)

list_issues / get_issue / list_teams / get_team / list_projects / get_project / list_users / get_user / list_issue_statuses / get_issue_status / list_comments / list_issue_labels / list_initiatives / get_initiative / list_cycles / list_documents / get_document / list_milestones / get_milestone / list_project_updates / get_status_updates

Bridge Tools

  • official_call_tool -- call any official Linear MCP tool (writes, unsupported reads, etc.)
  • list_official_tools -- list tools from an already-connected official MCP session
  • reconnect_official -- force reconnect official MCP (without clearing token cache)
  • refresh_cache -- force reload from local IndexedDB
  • get_cache_health -- check local + official backend status

Write Example

reconnect_official()
list_official_tools()
official_call_tool(name="create_issue", args={...})
official_call_tool(name="update_issue", args={...})

Environment Variables

Variable Default Purpose
LINEAR_OFFICIAL_MCP_TRANSPORT stdio stdio or http
LINEAR_OFFICIAL_MCP_COMMAND npx Command for stdio transport
LINEAR_OFFICIAL_MCP_ARGS -y mcp-remote https://mcp.linear.app/mcp Args for stdio transport
LINEAR_OFFICIAL_MCP_ENV JSON object, env for stdio child process
LINEAR_OFFICIAL_MCP_CWD Working directory for stdio child process
LINEAR_OFFICIAL_MCP_URL https://mcp.linear.app/mcp URL for http transport
LINEAR_OFFICIAL_MCP_HEADERS JSON headers for http transport
LINEAR_OFFICIAL_AUTH_RETRY_COOLDOWN_SECONDS 300 Numeric seconds. Pause official reconnect attempts after auth-like failures to avoid repeated OAuth popups
LINEAR_FAST_ACCOUNT_EMAILS Comma-separated; filter cache to these orgs
LINEAR_FAST_USER_ACCOUNT_IDS Comma-separated; direct account-id scope

Troubleshooting

npx: command not found -- Install Node.js, or set LINEAR_OFFICIAL_MCP_TRANSPORT=http.

Official calls unauthorized -- Call reconnect_official(ignoreCooldown=true) first. If OAuth is still required, re-run your configured official MCP auth flow (default: npx -y mcp-remote https://mcp.linear.app/mcp).

Local data seems stale -- Open Linear.app to trigger a sync, or call refresh_cache.

Linear local DB not found -- Check that it exists:

ls ~/Library/Application\ Support/Linear/IndexedDB/

Server is installed but not visible in Codex app -- Verify with codex mcp list. If listed there, fully restart Codex (quit and relaunch the app).

OAuth prompts appear repeatedly -- The server pauses official reconnect attempts for 300 seconds after auth-like failures. Tune with LINEAR_OFFICIAL_AUTH_RETRY_COOLDOWN_SECONDS, check get_cache_health, and use reconnect_official(ignoreCooldown=true) once after completing OAuth.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

oh_my_linear-0.5.8.tar.gz (127.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

oh_my_linear-0.5.8-py3-none-any.whl (129.0 kB view details)

Uploaded Python 3

File details

Details for the file oh_my_linear-0.5.8.tar.gz.

File metadata

  • Download URL: oh_my_linear-0.5.8.tar.gz
  • Upload date:
  • Size: 127.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.7

File hashes

Hashes for oh_my_linear-0.5.8.tar.gz
Algorithm Hash digest
SHA256 f82c73d58a960dfaaabc72f88e17bde48b99e4a0b682d5111e30e3560ca67cec
MD5 3dba492c2dcdc2be4cd72606457f8294
BLAKE2b-256 029a456ffa02c40487171f5a7284ff93e0fa08c4f6f12a739b4873e16585e058

See more details on using hashes here.

File details

Details for the file oh_my_linear-0.5.8-py3-none-any.whl.

File metadata

File hashes

Hashes for oh_my_linear-0.5.8-py3-none-any.whl
Algorithm Hash digest
SHA256 a3d05bb47556759c8f06ee8ca58c45796e97a44655199b6623e10f4db3af1515
MD5 f780c3cf318b85c5508621499a061eb2
BLAKE2b-256 42b5a4774515d8913f768da44d471ad6647412cce1550587b7c032506babb8f3

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page